2014-06-17 32 views
0

好的,所以我有一個帶有深度緩衝區和4種顏色附件的FBO。我想在我握住光標的位置讀取緩衝區,並從第四個顏色附件中讀取值。我似乎沒有管理這兩者中的任何一個。 我已寫下這個課程:帶有FBO附件的glreadpixels

class Picker3D{ 
    public: 
bool useAtachment; 
GLenum atachment; 
float PickerLastSignature; 
point3f PickerLastPos; 

Picker3D(bool useAtachment = true , GLenum atachment = GL_COLOR_ATTACHMENT3) : useAtachment(useAtachment) , atachment(atachment) { 

} 

void SetObjectSignature(float signature , GLSL_Prog prog){ 
    glUniform1f(glGetUniformLocation(prog.PR , "Signature") , signature); 
} 

float getSignature(float x , float y , float height){ 
    glGetError(); 
    if(useAtachment) 
     glReadBuffer(atachment); 

    cout << " Error message1 : " << glGetError() << endl ; 

    float *pixels = new float[4]; 
    glReadPixels(x , height - y , 1 , 1 , GL_RGB , GL_FLOAT , pixels); 
    PickerLastSignature = pixels[1]; 

    cout << " Error message2 : " << glGetError() << endl ; 

    return PickerLastSignature; 
} 

point3f get3DPosition(float x , float y , float height){ 
    //glReadBuffer(GL_DEPTH_ATTACHMENT); 

    double depth; 
    glReadPixels(x , y , 1 , 1 , GL_DEPTH_COMPONENT , GL_FLOAT , &depth); 

    cout << depth << endl; 

    int viewport[4]; 
    float *modelview; 
    double projection[16]; 
    double ModelView[16]; 

    modelview = mat4f::GetTopMatrix().returnTransposedMatrix().returnFloatArray(); 
    for(int i = 0 ; i < 16 ; i++){ 
     ModelView[i] = modelview[i]; 
    } 

    glGetDoublev(GL_PROJECTION_MATRIX, projection); 
    glGetIntegerv(GL_VIEWPORT, viewport); 

    double x1 , y1 , z1; 

    gluUnProject(x , height - y , depth , ModelView , projection , viewport , &x1 , &y1 , &z1); 

    PickerLastPos = point3f(x1 , y1 , z1); 
    return PickerLastPos; 
} 

};

我用它像這樣

//主迴路

BindFrameBuffer(); 
drawStuff(); 
Picker.get3DPosition(x , y , height); 
Picker.getSignature(x , y , height); 
UnbindBuffer(); 
drawSecondPass(); 
endDrawSecondPass(); 
// check Values of PickerLastPos and PickerLastSignature 
SwapBuffers(); 

altrough它正在屏幕上和getSignature給出錯誤1282(無效的操作深度是不會改變的,我覺得)與glReadBuffer一致。

主循環是:

   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 

      /// deferred pass 

      DefFBO->drawFBO(); 
      GeometryShader.UseNow(); 

      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 

      // load the view matrix and set the camera 
      cam.camera_set(); 
      cam.camera_get(GeometryShader); 

      // load identity for model matrix 
      mat4f::LoadIdentity(); 

      /// Geometry Drawing 

      mat4f::PushMatrix(); 

       mat4f::Translate(0 , 0 , -10); 
       Picker.SetObjectSignature(1.0f , GeometryShader); 
       T90.obj_rend(GeometryShader); 
       Picker.SetObjectSignature(2.0f , GeometryShader); 
       Town.obj_rend(GeometryShader); 

      mat4f::PopMatrix(); 

      Picker.get3DPosition(Window.Mouse->mouse_x , Window.Mouse->mouse_y , Window.Height); 

      /// setting the deferred read from buffer part 

      // last read from framebuffer 
      Picker.getSignature(Window.Mouse->mouse_x , Window.Mouse->mouse_y , Window.Height); 

      // unbind FBO 
      DefFBO->readFBO(); 

      // use fragment shader, for lights and for post processing 
      FragmentShader.UseNow(); 

      // send windows width and height and bind multiple textures 
      DefFBO->send_to_GLSL(FragmentShader.PR); 

      // send view matrix to the shader 
      cam.camera_get(FragmentShader); 

      glDepthMask(GL_FALSE); 
      glEnable(GL_DEPTH_TEST); 

      glUniform3f(glGetUniformLocation(FragmentShader.PR , "CameraPosition") , cam.x , cam.y , cam.z); 

      /// final draw 
      DefFBO->sendGlobalLight(FragmentShader , point3f(0 , 1 , 0) , point3f(0.3 , 0.3 , 0.3) , point3f(0.9 , 0.9 , 0.9)); 

      cout << Picker.PickerLastPos << endl; 

      DefFBO->end_read(); 

      glEnable(GL_DEPTH_TEST); 
      glDepthMask(GL_TRUE); 
+0

只是想指出我注意到的一個註釋掉的行:'// glReadBuffer(GL_DEPTH_ATTACHMENT)'。這是行不通的,用該命令設置的讀緩衝區是一個顏色緩衝區,所以只有FRONT/BACK/LEFT/RIGHT(或這些的某些組合)和'GL_COLOR_ATTACHMENTi'是有效值。雖然有太多的缺失代碼來評論其他任何東西;實際的FBO設置(例如附件所在的地方)甚至沒有列出。 'GL_INVALID_OPERATION'讓我相信你有錯誤的FBO界限,或者它實際上並沒有附加到'GL_COLOR_ATTACHMENT3'的東西。 –

回答

0

看來我不得不把FBO綁定用於讀取歌廳出來的數據顯示,截至@Andon指出。我與GL_DRAW_FRAMEBUFFER綁定。

+0

是的,這是將'GL_FRAMEBUFFER'分離爲'GL_DRAW_FRAMEBUFFER'和'GL_READ_FRAMEBUFFER'的想法。它允許您獨立控制您繪製的幀緩衝區以及您讀取的幀緩衝區。能夠做到這一點對於讀取和寫入幀緩衝區的操作至關重要,最顯着的是'glBlitFramebuffer()'。但它也適用於其他讀操作,如'glReadPixels()'。 –