2012-02-13 39 views
0

我有一個非常基本的片段着色器,我想輸出'gl_PrimitiveID'到我已定義的片段緩衝區對象(FBO)。下面是我的片段着色器:輸出gl_PrimitiveID到自定義幀緩衝區對象(FBO)的問題

#version 150 

uniform vec4 colorConst; 

out vec4 fragColor; 
out uvec4 triID; 

void main(void) 
{ 
    fragColor = colorConst; 
    triID.r = uint(gl_PrimitiveID); 
} 

設置我的FBO是這樣的:

GLuint renderbufId0; 
    GLuint renderbufId1; 
    GLuint depthbufId; 
    GLuint framebufId; 


    // generate render and frame buffer objects 
    glGenRenderbuffers(1, &renderbufId0); 
    glGenRenderbuffers(1, &renderbufId1); 
    glGenRenderbuffers(1, &depthbufId ); 
    glGenFramebuffers (1, &framebufId ); 


    // setup first renderbuffer (fragColor) 
    glBindRenderbuffer(GL_RENDERBUFFER, renderbufId0); 
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, gViewWidth, gViewHeight); 


    // setup second renderbuffer (triID) 
    glBindRenderbuffer(GL_RENDERBUFFER, renderbufId1); 
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB32UI, gViewWidth, gViewHeight); 


    // setup depth buffer 
    glBindRenderbuffer(GL_RENDERBUFFER, depthbufId); 
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, gViewWidth, gViewHeight); 


    // setup framebuffer 
    glBindFramebuffer(GL_FRAMEBUFFER, framebufId); 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbufId0); 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, renderbufId1); 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbufId ); 


    // check if everything went well 
    GLenum stat = glCheckFramebufferStatus(GL_FRAMEBUFFER); 
    if(stat != GL_FRAMEBUFFER_COMPLETE) { exit(0); } 


    // setup color attachments 
    const GLenum att[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1}; 
    glDrawBuffers(2, att); 


    // render mesh 
    RenderMyMesh() 


    // copy second color attachment (triID) to local buffer 
    glReadBuffer(GL_COLOR_ATTACHMENT1); 
    glReadPixels(0, 0, gViewWidth, gViewHeight, GL_RED, GL_UNSIGNED_INT, data); 

出於某種原因glReadPixels給了我一個 'GL_INVALID_OPERATION' 的錯誤?但是,如果我將'render_build1'的內部格式從'GL_RGB32UI'更改爲'GL_RGB',並且我在glReadPixels中使用'GL_FLOAT'而不是'GL_UNSIGNED_INT',那麼一切正常。有誰知道我爲什麼會得到'GL_INVALID_OPERATION'錯誤以及我如何解決它?

是否有輸出'gl_PrimitiveID'的替代方法?

PS:我要輸出的原因 'gl_PrimitiveID' 這樣這裏說明:Picking triangles in OpenGL core profile when using glDrawElements

回答

2

glReadPixels(0,0,gViewWidth,gViewHeight,GL_RED,GL_UNSIGNED_INT,數據);

正如on the OpenGL Wiki所述,傳送真正的整數數據時需要使用GL_RED_INTEGER。否則,OpenGL將嘗試在其上使用浮點轉換。

順便說一句,請確保您使用glBindFragDataLocation來設置片段着色器輸出到哪個緩衝區。或者,如果您使用GLSL 3.30或更高版本,則可以使用set it up explicitly in the shader

+0

非常感謝。那就是訣竅。你是否也碰巧知道如何(如果可能)在'uint'中輸出'gl_PrimitiveID'而不是'vec3'的顏色分量? – WesDec 2012-02-14 10:31:18

+1

@WesDec:如果你想寫一個'uint',那麼就寫一個'uint'。沒有規則輸出(或輸入)必須是矢量類型。並沒有規定輸出圖像需要全部四個值; GL_RUI32是一個完全有效的[圖像格式](http://www.opengl.org/wiki/Image_Format)。另外,「vec3」的顏色組件並不存在。「 「.r」與「.x」意思相同,意思與「.s」相同。所有的調酒面具都是一樣的。 – 2012-02-14 17:30:40

+0

謝謝我試圖在上面的第二個'glRenderbufferStorage'調用中使用GL_R32UI而不是GL_RGB32UI,但是我得到一個GL_INVALID_ENUM錯誤?難道它只是不支持我的OpenGL驅動程序(在Linux上)?我知道swizzle masks的意思是相同的,但'glReadPixels'參數讓你把它們看作是「顏色」,「深度」或「模板」(GL_RED,GL_RGBA,GL_DEPTH_STENCIL等),這就是我爲什麼要提到它們作爲「vec3」的顏色分量。 – WesDec 2012-02-15 11:36:21