2012-01-04 164 views
3

我正在渲染渲染纹理工作,但我有点麻烦。我正尝试在屏幕上渲染一个简单的四边形以确保一切正常。渲染纹理问题

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); 
} 
+0

你的FBO [完整](http://www.opengl.org/wiki/Framebuffer_Object#Framebuffer_Completeness)?你似乎没有调用'glCheckFramebufferStatus()'。 – genpfault 2012-01-04 21:28:43

+0

是的,回来了GL_FRAMEBUFFER_COMPLETE_EXT。 – rcapote 2012-01-04 21:59:33

回答

3

你能在当前矩阵(最有可能的模型视图)与glLoadIdentity复位。这就解释了为什么你的广场正在移动到屏幕的角落。

您已将拨打glPushAttrib的电话留言,但未拨打glPopAttrib。如果你没有在其他地方使用glPushAttrib这应该设置一个错误标志并且保持GL状态不变,但是我不知道是这种情况,并且假设属性堆栈总是为空并且要求麻烦。

glBindFrameBuffer

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

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

在您的代码中带有_EXT后缀的枚举可能与之前版本的OpenGL版本有关。教程容易让这样的细节过时。

检查您的环境&依赖于与您的OpenGL版本匹配的文档。如果由于某种原因您无法轻易确定您的OpenGL版本,请在调用glBindFrameBuffer后检查GL_INVALID_ENUM错误。

2

此代码似乎是错误的:

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

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

1

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

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(); 
} 
+0

在上面贴出的代码中,我手动将Matrix模式重置为正常设置。有没有办法通过推入/弹出到堆栈来做到这一点?我尝试了glPushMatrix/glPopMatrix,但是这看起来没有效果,因为我期望 – rcapote 2012-01-04 22:20:51

+2

'glPushAttrib'和'GL_TRANSFORM_BIT'将会保存矩阵模式以及其他一些状态。检查文档的细节。 – 01d55 2012-01-05 07:10:34