2012-01-04 211 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