渲染到纹理问题



我正试图让渲染纹理工作,但我有一点麻烦。我试图渲染一个简单的四边形屏幕,以确保一切都在工作。

    target->enable();
    glBegin(GL_QUADS);
    glColor4f(1.f, 0.f, 0.f, 1.f);
    glVertex3f(0.f, 0.f, 0.f);
    glColor4f(0.f, 1.f, 0.f, 1.f);
    glVertex3f(16.f, 0.f, 0.f);
    glColor4f(0.f, 0.f, 1.f, 1.f);
    glVertex3f(0.f, 16.f, 0.f);
    glColor4f(1.f, 1.f, 0.f, 1.f);
    glVertex3f(16.f, 16.f, 0.f);
    glEnd();
    target->disable();

当我将四边形正常绘制到屏幕上时,四边形按预期呈现。然而,当我在渲染目标启用的情况下绘制四边形时,四边形在屏幕的左下角被渲染,最终没有被渲染到目标。

RenderTarget::RenderTarget(GraphicsDevice *graphics, GLuint width, GLuint height) {
    mWidth = width;
    mHeight = height;
    // First create the depth buffer
    glGenRenderbuffers(1, &mDepth);
    glBindRenderbuffer(GL_RENDERBUFFER_EXT, mDepth);
    // Tell OpenGL that this renderbuffer is going to be a depth buffer
    glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, mWidth, mHeight);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth);
    glBindRenderbuffer(GL_RENDERBUFFER_EXT, 0);
    // Create the frame buffer texture
    glGenTextures(1, &mTexture);
    glBindTexture(GL_TEXTURE_2D, mTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glBindTexture(GL_TEXTURE_2D, 0);
    // Create the frame buffer
    glGenFramebuffers(1, &mFbo);
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, mFbo);
    // Attach the texture
    glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, mTexture, 0);
    //Attach the depth buffer
    glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mFbo);
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);

}
RenderTarget::~RenderTarget() {
    glDeleteBuffers(1, &mFbo);
    glDeleteBuffers(1, &mDepth);
    glDeleteTextures(1, &mTexture);
    mFbo = 0;
    mDepth = 0;
    mTexture = 0;
}
void RenderTarget::enable() {
    // Bind the frame buffer
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, mFbo);
    // store the glViewport and glEnable states
    //glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);
    glClearColor(1.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.f, 0.f, 0.f, 0.f);
    glLoadIdentity();
}
void RenderTarget::disable() {
    // Restore glViewport and glEnable states
    glPopAttrib();
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
}

您的启用是重置当前矩阵(最有可能的模型视图)与glLoadIdentity。这解释了为什么你的方块被移动到屏幕的角落。

您已经注释掉了对glPushAttrib的调用,但没有注释掉对glPopAttrib的匹配调用。如果你不使用glPushAttrib在其他任何地方,这应该设置一个错误标志,单独离开GL状态,但我不知道情况是这样的,它要求麻烦假设属性堆栈是,总是将是空的。

glBindFrameBuffer文档建议您应该使用GL_FRAMEBUFFERGL_DRAW_FRAMEBUFFER作为第一个参数:

target必须是GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER或GL_FRAMEBUFFER。如果将framebuffer对象绑定到GL_DRAW_FRAMEBUFFER或GL_READ_FRAMEBUFFER,它成为的目标分别执行呈现或回读操作,直到删除或另一个帧缓冲区被绑定到相应的绑定点。调用目标设置为GL_FRAMEBUFFER的glBindFramebuffer绑定framebuffer读取和绘制帧缓冲区目标。

带有_EXT后缀的枚举在你的代码中可能属于一个版本之前的OpenGL文档在那里。教程容易让这样的细节过时。

检查你的环境&依赖与你的OpenGL版本匹配的文档。如果由于某种原因你不能很容易地确定你的OpenGL版本,在调用glBindFrameBuffer后检查GL_INVALID_ENUM错误。

这段代码似乎有问题:

//Attach the depth buffer
glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mFbo);

你在这里做的是你试图将mFbo作为渲染缓冲区附加到mFbo。但是,您已经正确地附加了渲染缓冲区(这是在第一次调用glFramebufferRenderbuffer()时完成的)。我认为删除代码应该解决你的问题。

正如我所怀疑的,我的问题是在渲染FBO时正确设置glViewport和glOrtho。这段代码需要清理,但这里是我如何修复它。

void RenderTarget::enable() {
    // Bind the frame buffer
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, mFbo);
    // store the glViewport and glEnable states
    //glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);
    glViewport(0, 0, mWidth, mHeight);
    // projection matrix
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    // orthographic projection
    glOrtho(0, mWidth, 0, mHeight, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glClearColor(1.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.f, 0.f, 0.f, 0.f);
    glLoadIdentity();
}
void RenderTarget::disable() {
    // Restore glViewport and glEnable states
    //glPopAttrib();
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
    glViewport(0, 0, 1024, 768);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    // orthographic projection
    glOrtho(0, 1024, 768, 0, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

最新更新