// initialization
// create the FBO for the
public void AddFBO()
{
KTC_FBO fbo = new KTC_FBO();
// create framebuffer texture
GL.GenTextures(1, out fbo.FrameBufferID);
GL.BindTexture(TextureTarget.Texture2D, fbo.FrameBufferID);
GL.TexImage2D(TextureTarget.Texture2D,
0,
PixelInternalFormat.Rgba8,
1024,
1024,
0,
PixelFormat.Rgba,
PixelType.UnsignedByte,
IntPtr.Zero);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToBorder);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToBorder);
// create picking buffer texture
GL.GenTextures(1, out fbo.PickingBufferID);
GL.BindTexture(TextureTarget.Texture2D, fbo.PickingBufferID);
GL.TexImage2D(TextureTarget.Texture2D,
0,
PixelInternalFormat.Rgba8,
1024,
1024,
0,
PixelFormat.Rgba,
PixelType.UnsignedByte,
IntPtr.Zero);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToBorder);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToBorder);
// create depth buffer
GL.GenRenderbuffers(1, out fbo.DepthBufferID);
GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, fbo.DepthBufferID);
GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.DepthComponent24, 1024, 1024);
// create FBO
GL.GenFramebuffers(1, out fbo.FboID);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, fbo.FboID);
GL.FramebufferTexture2D(FramebufferTarget.Framebuffer,
FramebufferAttachment.ColorAttachment0,
TextureTarget.Texture2D,
fbo.FrameBufferID,
0);
GL.FramebufferTexture2D(FramebufferTarget.Framebuffer,
FramebufferAttachment.ColorAttachment1,
TextureTarget.Texture2D,
fbo.PickingBufferID,
0);
GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer,
FramebufferAttachment.DepthAttachment,
RenderbufferTarget.Renderbuffer,
fbo.DepthBufferID);
CheckFBO();
fbo.DisplayListID = CreateFramebufferDisplayList();
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
m_fbo.Add(fbo);
}
// create a VBO
public int AddRenderObject(KTC_RenderObject obj)
{
float[] data = new float[1];
byte offset = 0;
KTC_VBO vbo = new KTC_VBO();
GL.GenBuffers(1, out vbo.V_ID);
GL.BindBuffer(BufferTarget.ArrayBuffer, vbo.V_ID);
Byte4 c = new Byte4();
offset = 14;
data = new float[obj.data.Count * offset];
for (int i = 0; i < obj.data.Count; i++)
{
if(i % 3 == 0)
c = new Byte4(BitConverter.GetBytes(picking_offset + (uint)(i/3)));
data[offset * i] = (float)c.R / 255.0f;
data[offset * i + 1] = (float)c.G / 255.0f;
data[offset * i + 2] = (float)c.B / 255.0f;
data[offset * i + 3] = (float)c.A / 255.0f;
data[offset * i + 4] = obj.data[i].R;
data[offset * i + 5] = obj.data[i].G;
data[offset * i + 6] = obj.data[i].B;
data[offset * i + 7] = obj.data[i].A;
data[offset * i + 8] = obj.data[i].n_x;
data[offset * i + 9] = obj.data[i].n_y;
data[offset * i + 10] = obj.data[i].n_z;
data[offset * i + 11] = obj.data[i].x;
data[offset * i + 12] = obj.data[i].y;
data[offset * i + 13] = obj.data[i].z;
}
GL.BufferData(BufferTarget.ArrayBuffer,
(IntPtr)(data.Length * sizeof(float)),
data,
BufferUsageHint.StaticDraw);
//setup pointer
GL.SecondaryColorPointer(4, ColorPointerType.Float, 14 * sizeof(float), IntPtr.Zero);
GL.ColorPointer(4, ColorPointerType.Float, 14 * sizeof(float), (IntPtr)(4 * sizeof(float)));
GL.NormalPointer(NormalPointerType.Float, 14 * sizeof(float), (IntPtr)(8 * sizeof(float)));
GL.VertexPointer(3, VertexPointerType.Float, 14 * sizeof(float), (IntPtr)(11 * sizeof(float)));
vbo.Format = obj.bufferformat;
vbo.ElementCount = data.Length;
vbo.TriangleCount = obj.data.Count / 3;
vbo.PrimtiveType = obj.primitivetype;
vbo.Picking_Offset = (uint)picking_offset;
vbo.ObjectType = obj.objecttype;
vbo.Visible = true;
picking_offset += (uint)(obj.data.Count/3);
m_vbo.Add(vbo);
data = new float[1];
return m_vbo.Count - 1;
}
// render VBOs
public void RenderVBO(KTC_OpenGLCamera cam)
{
GL.PushAttrib(AttribMask.ViewportBit);
GL.Viewport(0, 0, width, height);
var look = cam.ModelViewProjectionMatrix;
GL.MatrixMode(MatrixMode.Projection);
GL.LoadMatrix(ref look);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();
DrawBuffersEnum[] bufs = new DrawBuffersEnum[2] { DrawBuffersEnum.ColorAttachment0,
DrawBuffersEnum.ColorAttachment1};
GL.DrawBuffers(bufs.Length, bufs);
GL.ClearColor(KTC_VisKitSetup.Setup.BackgroundColor);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
float[] c = { 1.0f, 1.0f, 1.0f, 1.0f };
GL.ClearBuffer(ClearBuffer.Color, 1, c);
GL.Enable(EnableCap.DepthTest);
GL.DepthFunc(DepthFunction.Lequal);
GL.ClearDepth(1.0f);
GL.PointSize(KTC_VisKitSetup.Setup.PointSize);
GL.LineWidth(KTC_VisKitSetup.Setup.LineWidth);
GL.UseProgram(shader.ShaderProgramID);
if (KTC_VisKitSetup.Setup.UseTexture)
GL.Uniform1(s_UseTexture, 1);
else
GL.Uniform1(s_UseTexture, 0);
Vector3 l = new Vector3(cam.LightPosition.X, cam.LightPosition.Y, cam.LightPosition.Z);
GL.Uniform3(s_LightPos, l);
foreach (KTC_VBO vbo in m_vbo)
{
if (!vbo.Visible)
continue;
GL.PushMatrix();
// enable needed arrays
GL.EnableClientState(ArrayCap.SecondaryColorArray);
GL.EnableClientState(ArrayCap.ColorArray);
GL.EnableClientState(ArrayCap.NormalArray);
GL.EnableClientState(ArrayCap.VertexArray);
GL.BindBuffer(BufferTarget.ArrayBuffer, vbo.V_ID);
GL.Translate(vbo.Position);
GL.DrawArrays(BeginMode.Triangles, 0, elementcount);
// diable needed arrays
GL.DisableClientState(ArrayCap.SecondaryColorArray);
GL.DisableClientState(ArrayCap.ColorArray);
GL.DisableClientState(ArrayCap.NormalArray);
GL.DisableClientState(ArrayCap.VertexArray);
GL.PopMatrix();
}
GL.UseProgram(0);
}
// render FBO on a quad in front of camera
public void DrawFBO()
{
GL.BindFramebuffer(FramebufferTarget.Framebuffer, m_fbo[0].FboID);
m_manager.RenderInTexture();
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
GL.Color3(Color.White);
GL.Viewport(0, 0, width, height);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();
GL.ClearColor(1f, 0f, 1f, 1f);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.Enable(EnableCap.Texture2D);
if(KTC_VisKitSetup.Setup.ShowPickingBuffer)
GL.BindTexture(TextureTarget.Texture2D, m_fbo[displayed_fbo].PickingBufferID);
else
GL.BindTexture(TextureTarget.Texture2D, m_fbo[displayed_fbo].FrameBufferID);
GL.CallList(m_fbo[0].DisplayListID);
GL.BindTexture(TextureTarget.Texture2D, 0);
GL.Disable(EnableCap.Texture2D);
}