I’m trying to render to a FBO and then draw the color texture and depth texture to screen (before moving foward and go for shadowmapping)
The color buffer is populated as expected (the color from the light POV)…but the depth color is empty !
I tried to debug with gDEBugg, looked inside the FBO and I can confirm there is only 0 inside the depth buffer texture.
It looks like this:
The lower part shows the camera POV, cube is there, on a black background, as expected. I draw the color texture from the light FBO on the upper right: it’s correct. I draw the depth texture to the upper left: It’s a big blank rectangle !
The code C ANSI and uses GLUT for portability, it is one file:
#ifdef _WIN32
#include "windows.h"
#endif
#include "GLUT/glut.h"
#include "glext.h"
#include <stdio.h>
#ifdef _WIN32
// As microsoft did not maintain openGL after version 1.1, Windows platform need to go throught this crap ; macosX and Linux are fine.
// This block simply retries openGL function needed for this example.
// I recommend to use GLEW instead of going this way. This is done this way only to ease beginner's compilation and portability
PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
// FrameBuffer (FBO) gen, bin and texturebind
PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT ;
PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT ;
PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT ;
PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT ;
void getOpenGLFunctionPointers(void)
{
glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress("glActiveTextureARB");
glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) wglGetProcAddress("glGenFramebuffersEXT");
glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) wglGetProcAddress("glBindFramebufferEXT");
glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)wglGetProcAddress("glFramebufferTexture2DEXT");
glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)wglGetProcAddress("glCheckFramebufferStatusEXT");
}
#endif
// Expressed as float so gluPerspective division returns a float and not 0 (640/480 != 640.0/480.0).
#define RENDER_WIDTH 640.0
#define RENDER_HEIGHT 480.0
#define SHADOW_MAP_RATIO 1
//Camera position
float p_camera[3] = {0,3,0};
//Camera lookAt
float l_camera[3] = {2,0,-10};
//Light position
float p_light[3] = {0,3,0};
//Camera lookAt
float l_light[3] = {0,0,-5};
// Hold id of the framebuffer for light POV rendering
GLuint fboId;
// Z values will be rendered to this texture when using fboId framebuffer
GLuint depthTextureId;
GLuint colorTextureId;
void generateShadowFBO()
{
int shadowMapWidth = RENDER_WIDTH/SHADOW_MAP_RATIO;
int shadowMapHeight = RENDER_HEIGHT/SHADOW_MAP_RATIO;
GLenum FBOstatus;
glGenTextures(1, &colorTextureId);
glBindTexture(GL_TEXTURE_2D, colorTextureId);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, shadowMapWidth, shadowMapHeight, 0, GL_RGBA, GL_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
// Try to use a texture depth component
glGenTextures(1, &depthTextureId);
glBindTexture(GL_TEXTURE_2D, depthTextureId);
// Normally filtering on depth texture is done bia GL_NEAREST, but Nvidia has a built-in support for Hardware filtering: use GL_LINEAR
// On ATI cards this fallback to GL_NEAREST anyway.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Three next lines are necessary if we wan to use the convenient shadow2DProj function in the shader.
// Otherwise we have to rely on texture2DProj
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
// create a framebuffer object
glGenFramebuffersEXT(1, &fboId);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
// attach the texture to FBO color attachment point
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D, colorTextureId, 0);
// attach the texture to FBO depth attachment point
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, depthTextureId, 0);
// check FBO status
FBOstatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(FBOstatus != GL_FRAMEBUFFER_COMPLETE_EXT)
printf("GL_FRAMEBUFFER_COMPLETE_EXT failed, CANNOT use FBO
");
// switch back to window-system-provided framebuffer
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
void setupMatrices(float position_x,float position_y,float position_z,float lookAt_x,float lookAt_y,float lookAt_z)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(75,RENDER_WIDTH/RENDER_HEIGHT,1,200);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(position_x,position_y,position_z,lookAt_x,lookAt_y,lookAt_z,0,1,0);
}
void update(void)
{
}
void drawObjects(void)
{
glPushMatrix();
glTranslatef(2,0,-5);
glutSolidCube(1);
glPopMatrix();
}
void renderScene(void)
{
update();
//glEnable(GL_BLEND);
//glBlendFunc(GL_SRC_ALPHA,GL_ONE);
glViewport(0,0,RENDER_WIDTH,RENDER_HEIGHT);
//First step: Render from the light POV to a FBO
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId); //Rendering offscreen
glClearColor(1,0,0,1.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glDepthMask(GL_TRUE);
//glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); //Disable color rendering, we only want to write to the Z-Buffer
setupMatrices(p_light[0],p_light[1],p_light[2],l_light[0],l_light[1],l_light[2]);
glColor4f(1,1,1,1);
drawObjects();
// Now rendering from the camera POV, using the FBO to generate shadows
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0); //Rendering to screen
//glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); //Enabling color write (previously disabled for light POV z-buffer rendering)
setupMatrices(p_camera[0],p_camera[1],p_camera[2],l_camera[0],l_camera[1],l_camera[2]);
glColor4f(1,1,1,1);
drawObjects();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-RENDER_WIDTH/2,RENDER_WIDTH/2,-RENDER_HEIGHT/2,RENDER_HEIGHT/2,1,200);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//glColor4f(1,1,1,1);
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
//glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,colorTextureId);
glTranslated(0,0,-1);
glBegin(GL_QUADS);
glTexCoord2d(0,0);glVertex2d(0,0);
glTexCoord2d(0,1);glVertex2d(0,RENDER_HEIGHT/2);
glTexCoord2d(1,1);glVertex2d(RENDER_WIDTH/2,RENDER_HEIGHT/2);
glTexCoord2d(1,0);glVertex2d(RENDER_WIDTH/2,0);
glEnd();
//glTranslated(-RENDER_HEIGHT/2,0,0);
glBindTexture(GL_TEXTURE_2D,depthTextureId);
glBegin(GL_QUADS);
glTexCoord2d(0,0);glVertex3f(0,0,0);
glTexCoord2d(0,1);glVertex3f(0,RENDER_HEIGHT/2,0);
glTexCoord2d(1,1);glVertex3f(-RENDER_WIDTH/2,RENDER_HEIGHT/2,0);
glTexCoord2d(1,0);glVertex3f(-RENDER_WIDTH/2,0,0);
glEnd();
glDisable(GL_TEXTURE_2D);
glutSwapBuffers();
}
void processNormalKeys(unsigned char key, int x, int y) {
if (key == 27)
exit(0);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
glutInitWindowPosition(100,100);
glutInitWindowSize(RENDER_WIDTH,RENDER_HEIGHT);
glutCreateWindow("GLSL Shadow mapping");
// This call will grab openGL extension function pointers.
// This is not necessary for macosx and linux
#ifdef _WIN32
getOpenGLFunctionPointers();
#endif
generateShadowFBO();
glutDisplayFunc(renderScene);
glutIdleFunc(renderScene);
glutKeyboardFunc(processNormalKeys);
glutMainLoop();
}
I’m suspect the error is in the FBO creation function: generateShadowFBO but I can’t spot it !
Help me obi-wan kenoby you are my only hope !