OpenGL rendering from FBO to screen
Asked Answered
P

1

5

The idea is to render specific parts of a scene in a FrameBuffer object in different color attachments and then combining those using the depth buffer for the final image. in the first step I want only to render to a single attachment and then to the screen. I'm using glut for this purpose and the EXT_framebuffer_object specification due to my old graphics card. In the main function I have:

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitWindowSize(600, 512);
    glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
    int mainHandle = glutCreateWindow("Demo");
    glutSetWindow(mainHandle);
    glutDisplayFunc(RenderCallback);
    glutReshapeFunc(ReshapeCallback);
    glutIdleFunc(IdleCallback);
    glutKeyboardFunc(KeyboardCallback);
    glutSpecialFunc(ArrowKeyCallback);
    glutMouseFunc(MouseCallback);
    glutMotionFunc(MotionCallback);

    MotionCallback(0,0);
    atexit(ExitNx);

    // Setup default render states
    glClearColor(0.3f, 0.4f, 0.5f, 1.0);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_COLOR_MATERIAL);

    // Setup lighting
    glEnable(GL_LIGHTING);
    float ambientColor[]    = { 0.0f, 0.1f, 0.2f, 0.0f };
    float diffuseColor[]    = { 1.0f, 1.0f, 1.0f, 0.0f };       
    float specularColor[]   = { 0.0f, 0.0f, 0.0f, 0.0f };       
    float position[]        = { 100.0f, 100.0f, 400.0f, 1.0f };     
    glLightfv(GL_LIGHT0, GL_AMBIENT, ambientColor);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseColor);
    glLightfv(GL_LIGHT0, GL_SPECULAR, specularColor);
    glLightfv(GL_LIGHT0, GL_POSITION, position);
    glEnable(GL_LIGHT0);
    GLenum status,st1,st2;                                            
    GLint colorBufferCount ;
    glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &colorBufferCount);   
    printf("Max number of attachments:%d \n " ,colorBufferCount);
    //initialising FBO
    glGenFramebuffersEXT(1,&fb);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fb);
    //attaching an image to render to
    glGenRenderbuffersEXT(1,&colorbf);
    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,colorbf);
    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_RGBA8,600,512);
    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,   GL_RENDERBUFFER_EXT, colorbf);
    //creating depht buffer
    glGenRenderbuffersEXT(1, &depth_rb);
    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb);
    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, 600, 512);
    //attaching the depth buffer to the FBO
    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb);
    st1=glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    //checking for errors
    st2=glGetError();
    if(st1==GL_FRAMEBUFFER_COMPLETE_EXT)
        printf("so far so good\n ");
    else
        if(st1==GL_FRAMEBUFFER_UNSUPPORTED_EXT)
            printf("not good");
    const GLubyte *sir= new GLubyte [256];
    sir=gluErrorString(st1);
    printf("error received %s \n", sir);

    glutMainLoop();
}

In the display callback function I have

void RenderCallback()
{
    // Setup projection matrix
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60.0f, (float)glutGet(GLUT_WINDOW_WIDTH)/(float)glutGet(GLUT_WINDOW_HEIGHT), 1.0f, 10000.0f);
    gluLookAt(gEye.x, gEye.y, gEye.z, gEye.x + gDir.x, gEye.y + gDir.y, gEye.z + gDir.z, 0.0f, 1.0f, 0.0f);

    // Setup modelview matrix
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); //setting our FBO to render to
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);  
    //render code 
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0); //unbiding

    //now I wish to see what I have written in the colorbf attachment , most likely my mistake is in the following to come
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity();
    //should I have done something else before?
    glutSwapBuffers();
}

The output is an empty scene.

Panchito answered 1/5, 2012 at 14:14 Comment(0)
G
11
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);

GL_COLOR_ATTACHMENT0_EXT is not a valid argument for glDrawBuffer().

Add a texture attachment if you want to visualize your FBO. Just bind your texture attachment after you're done rendering to your FBO and draw a full-screen textured quad.

Gouty answered 1/5, 2012 at 15:33 Comment(6)
The moral of the story is: check for errors after every call. At least in debug builds.Ambassadress
BuGLe should help with that if you're on Linux. There's also glintercept for Windows.Gouty
thank-you for your help, after a bit of experimenting it worked the way I was expecting it. If I may ask another question: how should I go about in combining several images that were rendered on different computers into a single one using the depth-buffer on another central computer. Must I read the images and the value of the depth-buffers and send them to central computer?Panchito
You might give Equalizer a shot if you don't want to do the network footwork yourself.Gouty
Sadly I must do the networking, to that scope I use MPI, but before testing I want to do experiment on the same computer in order to understand and view the results. If you know some links that could point me to the right direction could you please share them?Panchito
Nope, Equalizer was the only thing I know of that fit your "networked OpenGL" motif. You'll have to slurp and transfer the buffers yourself.Gouty

© 2022 - 2024 — McMap. All rights reserved.