glreadpixels with FBO attachment

glreadpixels with FBO attachment

本文关键字:attachment FBO with glreadpixels      更新时间:2023-10-16

好的,我有这个带有深度缓冲和4个颜色附件的FBO。我想读取光标所在位置的深度缓冲区和第四个颜色附件中的值。这两件事我似乎都做不到。我写了这个类:

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();  

深度没有改变,尽管它在屏幕上工作,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);

似乎我必须绑定读取fbo以便从中获取数据,正如@Andon指出的那样。我绑定了GL_DRAW_FRAMEBUFFER。