我的问题是OpenGL渲染到主窗口,虽然我绑定了我想要使用的Framebuffer。
这是我的主渲染方法
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
renderer.BeginFrame();
renderer.RenderEntity(testEntity);
renderer.EndFrame();
SwapBuffers();
}
这是我的渲染器
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;
}
}
这是我的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);
}
}
预期的结果是黑色四边形,因为当我发现我的模型仍然呈现在屏幕上时,我一直在实现Texturing。当我在EndRendering()中调出GL.DrawElements调用时,我发现了这一点,它应该将四边形渲染到屏幕上。当我现在不画那个四边形时,图像仍然出现。
我做错了什么?
答案 0 :(得分:1)
渲染缓冲区不是帧缓冲对象:
frameBufferID = GL.GenRenderbuffer();
当您尝试绑定从glGenRenderbuffers
作为帧缓冲区获取的ID时,您将从GL_INVALID_OPERATION
收到glBindFramebuffer()
错误,该命令将不会产生进一步的影响(离开默认帧缓冲区绑定)。
新的FBO名称是通过glGenFramebuffers
生成的,因此您应该使用它。