My problem is that OpenGL renders to the Main-Window, although I bound the Framebuffer I want to use.
This is my Main Rendering-Method
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
renderer.BeginFrame();
renderer.RenderEntity(testEntity);
renderer.EndFrame();
SwapBuffers();
}
This is my Renderer
class Renderer
{
List<Vertex> screenQuadVertecies = new List<Vertex>
{
new Vertex(new Vector3(-1, 1, 0), new Vector3()),
new Vertex(new Vector3(1, 1, 0), new Vector3()),
new Vertex(new Vector3(-1, -1, 0), new Vector3()),
new Vertex(new Vector3(1, -1, 0), new Vector3())
};
List<int> screenQuadIndices = new List<int>
{
0, 1, 2,
1, 2, 3
};
List<Vector2> screenQuadUVs = new List<Vector2>
{
new Vector2(0, 0),
new Vector2(1, 0),
new Vector2(0, 1),
new Vector2(1, 1)
};
TexturedMesh screenQuad;
Framebuffer mainPassFramebuffer;
Camera activeCamera;
Shader ModelShader;
Shader PostProcessingShader;
int width, height;
public Renderer(int width, int height)
{
this.width = width;
this.height = height;
ModelShader = new MainShader();
PostProcessingShader = new PostProcessingShader();
mainPassFramebuffer = new Framebuffer(width, height);
screenQuad = new TexturedMesh(screenQuadVertecies, screenQuadIndices, screenQuadUVs);
}
public void BeginFrame()
{
mainPassFramebuffer.EndRendering();
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
mainPassFramebuffer.ClearBuffer();
mainPassFramebuffer.BeginRendering();
}
public void EndFrame()
{
mainPassFramebuffer.EndRendering();
mainPassFramebuffer.BindTexture();
PostProcessingShader.UseShader();
screenQuad.PrepareRendering();
GL.DrawElements(PrimitiveType.Triangles, 6, DrawElementsType.UnsignedInt, 0);
screenQuad.EndRendering();
PostProcessingShader.UnuseShader();
}
public void RenderEntity(Entity e)
{
e.Mesh.PrepareRendering();
ModelShader.UseShader();
ModelShader.LoadCamera(activeCamera);
ModelShader.LoadModel(e.GetModelMatrix());
GL.DrawElements(PrimitiveType.Triangles, e.Mesh.GetSize(), DrawElementsType.UnsignedInt, 0);
ModelShader.UnuseShader();
}
public void RenderTerrain(Terrain t)
{
foreach (var chunk in t.chunks)
{
RenderEntity(chunk.GetEntity());
}
}
public void SetActiveCamera(Camera camera)
{
activeCamera = camera;
}
}
And this is my Framebuffer Class
class Framebuffer
{
int frameBufferID;
int textureID;
int width, height;
public Framebuffer(int width, int height)
{
this.width = width;
this.height = height;
frameBufferID = GL.GenRenderbuffer();
GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBufferID);
textureID = CreateTexture();
GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, textureID, 0);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
}
protected int CreateTexture()
{
int returnID;
returnID = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, returnID);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, width, height, 0, PixelFormat.Rgb, PixelType.UnsignedByte, (IntPtr)0);
int nearest = (int)TextureMagFilter.Nearest;
GL.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, ref nearest);
GL.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, ref nearest);
return returnID;
}
public void BeginRendering()
{
GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBufferID);
GL.Viewport(new System.Drawing.Point(0, 0), new System.Drawing.Size(width, height));
}
public void EndRendering()
{
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
}
public void BindTexture()
{
GL.BindTexture(TextureTarget.Texture2D, textureID);
}
public void ClearBuffer()
{
GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBufferID);
GL.Viewport(new System.Drawing.Point(0, 0), new System.Drawing.Size(width, height));
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
}
}
The expected result is a black quad because I have been implementing Texturing when I discovered that my Model still renders to the screen. I found that out when I commentend out the GL.DrawElements call in EndRendering() which should render the quad to the screen. When I now don't draw that quad the image still appears.
What am I doing wrong?
A render buffer is not a framebuffer object:
When you try to bind an ID you got from
glGenRenderbuffers
as a framebuffer, you will get anGL_INVALID_OPERATION
error fromglBindFramebuffer()
, and the command will have no further effect (leaving the default framebuffer bound).New FBO names are generated via
glGenFramebuffers
, so you should use that.