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?
>
marks at the beginning of lines. Those are for when you're quoting someone else, not for when you're quoting yourself. – Nicol Bolas