0
votes

I'd like to render a scene with opengl with a lot of light sources. However in opengl max lights sources are 8. Im trying to use FBOs to do that. So i would have something like that render to FBO1 scene with 8 lights and then in FBO2 = FBO2 + FBO1 ( adding texels components ). So FBO2 would accumulate final image. (thats the idea ). However i have "some" coding problems :) Here is my code:

Rendering :

    glEnable(GL_TEXTURE_RECTANGLE_NV);
glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT); // Push our glEnable and glViewport states 
glViewport(0, 0, OPT.m_nWidth, OPT.m_nHeight);

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the depth and colour buffers 
glLoadIdentity();  // Reset the modelview matrix 


int iIndeks = 0, iLoopIndeks = 0, iLightsUsed = 0;
float *pM = scene3D->oCamera.SetMatrixs();
glLoadMatrixf(pM);
delete []pM;

int iAccumMult = xLightsToRender.size/MAX_OPENGL_LIGHTS;

while(iIndeks < xLightsToRender.size )
{       
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, iFrameBufferAccumulation); 

    glShadeModel(GL_SMOOTH);
    float *pM = scene3D->oCamera.SetMatrixs();
    glLoadMatrixf(pM);
    delete []pM;

    glMatrixMode(GL_MODELVIEW);

    iLightsUsed = xLightsToRender.size > (iLoopIndeks+1) * MAX_OPENGL_LIGHTS ? MAX_OPENGL_LIGHTS : (xLightsToRender.size - iLoopIndeks * MAX_OPENGL_LIGHTS);

    iIndeks+=iLightsUsed;
    glPushMatrix();
    //initilise lights
    setLights( iLoopIndeks * MAX_OPENGL_LIGHTS,  iLightsUsed, xLightsToRender );
    for (int i=0;i<scene3D->data.m_nObjectCount;i++)
    {
        //glutSolidTeapot(1.0f); // Render a teapot 
        scene3D->RenderObjectWithOpenGL(i);
    }
    if( scene3D->data.bMovingObjectIni   )
    {
        scene3D->RenderObjectWithOpenGL( -1, true);
    }       



    glPopMatrix();

    iLoopIndeks++;
    //xShader.bind();

    //xShader.unbind();
    glPopAttrib(); // Restore our glEnable and glViewport states 
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Unbind our texture  
    //render to second buffer
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, iFrameBuffer); 
    glBindTexture(GL_TEXTURE_RECTANGLE_NV, iTextureImgAccumulation); // Bind our frame buffer texture 
    glTranslatef(0.0f, 0.0f, -2.0f); 
    glBegin(GL_QUADS);
    glTexCoord2f(0,OPT.m_nHeight);
    glVertex3f(-1,-1,0);

    glTexCoord2f(OPT.m_nWidth,OPT.m_nHeight);
    glVertex3f(1,-1,0);

    glTexCoord2f(OPT.m_nWidth,0);
    glVertex3f(1,1,0);

    glTexCoord2f(0,0);
    glVertex3f(-1,1,0);

    glEnd();
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Unbind our texture  
}

Here is FBOs initialisation:

    void OpenGlRenderer::initFrameBufferTexture(void) 
  {  
glGenTextures(1, &iTextureImg); // Generate one texture  


glEnable(GL_TEXTURE_RECTANGLE_NV);  
glBindTexture(GL_TEXTURE_RECTANGLE_NV, iTextureImg);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD/*GL_DECAL*/);
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGB16F /*GL_FLOAT_R32_NV*/, OPT.m_nWidth, OPT.m_nHeight, 0, GL_RED, GL_FLOAT, NULL);

glGenTextures(1, &iTextureImgAccumulation); // Generate one texture  
glEnable(GL_TEXTURE_RECTANGLE_NV);  
glBindTexture(GL_TEXTURE_RECTANGLE_NV, iTextureImgAccumulation);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD/*GL_DECAL*/);
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGB16F /*GL_FLOAT_R32_NV*/, OPT.m_nWidth, OPT.m_nHeight, 0, GL_RED, GL_FLOAT, NULL);



// Setup the basic texture parameters  



// Unbind the texture  
glBindTexture(GL_TEXTURE_RECTANGLE_NV, 0);  
    }


    void OpenGlRenderer::initFrameBufferDepthBuffer(void) 
    {  

    glGenRenderbuffersEXT(1, &iDepthBuffer); // Generate one render buffer and store the ID in iDepthBuffer  
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, iDepthBuffer); // Bind the iDepthBuffer render buffer  

    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,  OPT.m_nWidth, OPT.m_nHeight); // Set the render buffer storage to be a depth component, with a width and height of the window  

    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, iDepthBuffer); // Set the render buffer of this buffer to the depth buffer  

    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); // Unbind the render buffer  
    }   


    void OpenGlRenderer::initFrameBuffer(void) 
    {  
   initFrameBufferDepthBuffer(); // Initialize our frame buffer depth buffer  

   initFrameBufferTexture(); // Initialize our frame buffer texture  

   glGenFramebuffersEXT(1, &iFrameBufferAccumulation); // Generate one frame buffer and store the ID in iFrameBufferAccumulation  
   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, iFrameBufferAccumulation); // Bind our frame buffer  

   glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV, iTextureImgAccumulation, 0); // Attach the texture fbo_texture to the color buffer in our frame buffer  

   glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, iDepthBuffer); // Attach the depth buffer iDepthBuffer to our frame buffer  

   glGenFramebuffersEXT(1, &iFrameBuffer); // Generate one frame buffer and store the ID in iFrameBufferAccumulation  
   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, iFrameBuffer); // Bind our frame buffer  

   glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_NV, iTextureImg, 0); // Attach the texture fbo_texture to the color buffer in our frame buffer  

   glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, iDepthBuffer); // Attach the depth buffer iDepthBuffer to our frame buffer  

   GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); // Check that status of our generated frame buffer  
   checkFramebufferStatus();  
   if (status != GL_FRAMEBUFFER_COMPLETE_EXT) // If the frame buffer does not report back as complete  
   {  
    std::cout << "Couldn't create frame buffer" << std::endl; // Output an error to the console  
    exit(0); // Exit the application  
   }  
  }

So basically i want to render to iFrameBufferAccumulation and then relative Texture rendere to iFrameBuffer each time with glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD); which should effectively add these two framebuffers? (or do i need to use shaders)

Also i d like to ask if i can put lightning intensity bigger then 1.0 (atm it works like that in my program - function setLights ) and it will render correct results to FBO? I use GL_RGB16F texture format. Is it ok for that or i need to use 32 bit texture? If soo do i need to use shaders to display FBO after rendering?

1
Welcome to Stack Overflow. In the future, you shouldn't put > marks at the beginning of lines. Those are for when you're quoting someone else, not for when you're quoting yourself.Nicol Bolas

1 Answers

1
votes

Also i d like to ask if i can put lightning intensity bigger then 1.0 (atm it works like that in my program - function setLights ) and it will render correct results to FBO? I use GL_RGB16F texture format. Is it ok for that or i need to use 32 bit texture? If soo do i need to use shaders to display FBO after rendering?

In general, no. Virtually all fixed-function operations are clamped, either at the time of texture fetch or at the time they're written to the framebuffer, or some other time than that.

If you want to do real floating-point operations, then you need to abandon fixed-function and switch to shaders.