C# 向FBO开放TK图纸,着色不符合预期
我有一个用于帧缓冲区对象的实用程序类,用于生成FBO、绑定它们、渲染到它们,以及将它们作为2d纹理渲染到屏幕 使用这个类时,我可以成功地制作fbo纹理,渲染到它们,然后渲染到屏幕 然而,一旦我把颜色渲染到屏幕上,它们看起来就乱七八糟了 似乎正在发生的是,我设置为绘图颜色的颜色最终成为FBO的背景色(但前提是我在设置颜色后进行实际绘图调用),并且我绘制的绘图始终以黑色结束 基于我的代码,我期望的是一个白色背景的纹理,上面有两个小的彩色矩形(一个紫色和一个青色),绘制到屏幕上两次 我得到的是: 带有两个黑色小矩形的青色背景 源代码如下: FboRenderTexture.csC# 向FBO开放TK图纸,着色不符合预期,c#,opengl,graphics,opentk,fbo,C#,Opengl,Graphics,Opentk,Fbo,我有一个用于帧缓冲区对象的实用程序类,用于生成FBO、绑定它们、渲染到它们,以及将它们作为2d纹理渲染到屏幕 使用这个类时,我可以成功地制作fbo纹理,渲染到它们,然后渲染到屏幕 然而,一旦我把颜色渲染到屏幕上,它们看起来就乱七八糟了 似乎正在发生的是,我设置为绘图颜色的颜色最终成为FBO的背景色(但前提是我在设置颜色后进行实际绘图调用),并且我绘制的绘图始终以黑色结束 基于我的代码,我期望的是一个白色背景的纹理,上面有两个小的彩色矩形(一个紫色和一个青色),绘制到屏幕上两次 我得到的是: 带有
public class FboRenderTexture : IDisposable
{
public int textureId = 0;
private int fboId = 0;
public int Width;
public int Height;
public FboRenderTexture(int width, int height)
{
Width = width;
Height = height;
Init();
}
//semi pseudocode
public void DrawToScreen(float xoffset = 0, float yoffset = 0)
{
if (textureId != -1)
{
GL.BindTexture(TextureTarget.Texture2D, textureId);
GL.Begin(BeginMode.Quads);
//todo : might also flip the texture since fbo's have right handed coordinate systems
GL.TexCoord2(0.0, 0.0);
GL.Vertex3(xoffset, yoffset, 0.0);
GL.TexCoord2(0.0, 1.0);
GL.Vertex3(xoffset, yoffset+Height, 0.0);
GL.TexCoord2(1.0, 1.0);
GL.Vertex3(xoffset+Width, yoffset+Height, 0.0);
GL.TexCoord2(1.0, 0.0);
GL.Vertex3(xoffset+Width, yoffset, 0.0);
GL.End();
}
}
private void Init()
{
// Generate the texture.
textureId = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, textureId);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, Width, Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
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 a FBO and attach the texture.
GL.Ext.GenFramebuffers(1, out fboId);
GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, fboId);
GL.Ext.FramebufferTexture2D(FramebufferTarget.FramebufferExt,
FramebufferAttachment.ColorAttachment0Ext, TextureTarget.Texture2D, textureId, 0);
// Disable rendering into the FBO
GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);
}
// Track whether Dispose has been called.
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
// Clean up what we allocated before exiting
if (textureId != 0)
GL.DeleteTextures(1, ref textureId);
if (fboId != 0)
GL.Ext.DeleteFramebuffers(1, ref fboId);
disposed = true;
}
}
}
public void BeginDrawing()
{
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, fboId);
GL.DrawBuffer(DrawBufferMode.ColorAttachment0);
GL.PushAttrib(AttribMask.ViewportBit);
GL.Viewport(0, 0, Width, Height);
}
public void EndDrawing()
{
GL.PopAttrib();
GL.Ext.BindFramebuffer(FramebufferTarget.DrawFramebuffer, 0); // disable rendering into the FBO
}
}
用法
public class Buffers : CreativeSharp.core.CSInstance //inherits from OpenTK.GameWindow, adds some simple drawing stuff.
{
private FboRenderTexture buffer;
public Buffers() : base(800, 600, "buffers")
{
GL.Enable(EnableCap.Texture2D);
buffer = new FboRenderTexture(128, 128);
NoStroke();
this.Closed += Buffers_Closed;
}
private void SetupBuffer()
{
buffer.BeginDrawing();
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit);
GL.ClearColor(1.0f, 1.0f, 1.0f, 1.0f);
GL.Color4(1f, 0f, 1f, 0f);
DrawRectangle(10,10, 30, 30);
GL.Color4(0f, 1f, 1f, 1f);
DrawRectangle(50, 10, 30, 30);
GL.Color4(1f, 1f, 1f);
buffer.EndDrawing();
}
void Buffers_Closed(object sender, EventArgs e)
{
buffer.Dispose();
}
public override void DrawContent()
{
SetupBuffer();
GL.ClearColor(1.0f, 1.0f, 1.0f, 1.0f);
GL.Color4(1f, 1f, 1f, 1f);
buffer.DrawToScreen(0,0);
buffer.DrawToScreen(512,0);
}
public override void Update()
{
}
private void DrawRectangle(float x, float y, float w, float h)
{
GL.Begin(PrimitiveType.Quads);
GL.Vertex3(x, y, 0);
GL.Vertex3(x + w, y, 0);
GL.Vertex3(x + w, y + h, 0);
GL.Vertex3(x, y + h, 0);
GL.End();
}
}
有点尴尬的是,我的问题的原因是,我没有设置白色作为绘图颜色,然后再绘制fbo的纹理。
这导致颜色完全错了。哦,请考虑不要使用非常旧的废弃固定函数流水线。这比使用顶点缓冲区和着色器会引起更多的问题。所以你是说,如果我放弃即时模式绘制,使用顶点缓冲区,并滚动我自己的着色器,我可能不会有这个问题?我并没有觉得我使用的任何东西都不受欢迎。事实上,我不知道它是否解决了你的问题,但根据我的经验,当我完全远离不受欢迎的东西时,我得到的错误更少。回到你的问题:是的,所有的
GL.Color4
,GL.Vertex3
,还有很多都不推荐使用。哦,等等,它们从2009年开始在opengl中就完全不推荐使用了。。。天哪,我觉得我一直生活在岩石下。谢谢。不过为了学习,我还是很想知道发生了什么以及为什么会发生。所以如果有人能给我线索,请随意。