I am attempting to render depth information into a cube map for use with shadows from a point light.
I have been using this site as a guide:
http://sunandblackcat.com/tipFullView.php?l=eng&topicid=36
I am unsure how to display the textures that are being created in the fbo so that I can visualize the depths written from the depth shaders. Or if they are being created correctly within the fbo. I have also looked at ofxCubeMap, but can’t seem to get it working for this purpose.
I am using the programmable renderer and openGL 3.3 on OSX 10.9.
Below is the code I am using to generate the cube map and fbo. Sorry for the long post.
void Init( int asize ) {
mSize = asize;
// Create the FBO
glGenFramebuffers(1, &m_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
// Create the depth buffer
glGenTextures(1, &m_depth);
glBindTexture(GL_TEXTURE_2D, m_depth);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, mSize, mSize, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depth, 0);
glBindTexture(GL_TEXTURE_2D, 0);
// Create the cube map
glGenTextures(1, &m_shadowMap);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_shadowMap);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
// glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
// glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
for (uint i = 0 ; i < 6 ; i++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_R32F, mSize, mSize, 0, GL_RED, GL_FLOAT, NULL);
// glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT32F, mSize, mSize, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
}
// Disable writes to the color buffer
// glDrawBuffer(GL_NONE);
// Disable reads from the color buffer
// glReadBuffer(GL_NONE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X, m_shadowMap, 0 );
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
switch(status) {
case GL_FRAMEBUFFER_COMPLETE:
ofLogVerbose("ofFbo") << "FRAMEBUFFER_COMPLETE - OK";
return true;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
break;
#ifndef TARGET_PROGRAMMABLE_GL
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_FORMATS";
break;
#endif
case GL_FRAMEBUFFER_UNSUPPORTED:
ofLogError("ofFbo") << "FRAMEBUFFER_UNSUPPORTED";
break;
#ifndef TARGET_OPENGLES
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
ofLogWarning("ofFbo") << "FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER";
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_READ_BUFFER";
break;
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
ofLogError("ofFbo") << "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE";
break;
#endif
default:
ofLogError("ofFbo") << "UNKNOWN ERROR " << status;
break;
}
// disable
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
}
and the bind for writing into the textures:
void BindForWriting( int CubeFace) {
ofPushView();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + CubeFace, m_shadowMap, 0 );
glDrawBuffer(GL_COLOR_ATTACHMENT0);
// glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + CubeFace, m_shadowMap, 0 );
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
cam.setFov( 90 );
cam.setNearClip( 1 );
cam.setFarClip( 1000 );
if( CubeFace == 0 ) {
cam.lookAt( ofVec3f(1,0,0), ofVec3f(0,1,0) );
} else if( CubeFace == 1 ) {
cam.lookAt( ofVec3f(-1,0,0), ofVec3f(0,1,0) );
} else if( CubeFace == 2 ) {
cam.lookAt( ofVec3f(0,1,0), ofVec3f(0,0,-1) );
} else if( CubeFace == 3 ) {
cam.lookAt( ofVec3f(0,-1,0), ofVec3f(0,0,1) );
} else if( CubeFace == 4 ) {
cam.lookAt( ofVec3f(0,0,1), ofVec3f(0,-1,0) );
} else if( CubeFace == 5 ) {
cam.lookAt( ofVec3f(0,0,-1), ofVec3f(0,-1,0) );
}
// glLoadMatrixf( tcam.getProjectionMatrix() );
cam.begin( ofRectangle( 0, 0, mSize, mSize ));
}
// vert shader for writing depth //
#version 330
// set automatically by OF //
in vec4 position;
// these are passed in from OF programmable renderer
uniform mat4 viewMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 modelViewProjectionMatrix;
uniform mat4 u_modelMat;
// world space position of the vertex to the fragment shader
out vec4 o_worldSpacePosition;
void main( void ) {
o_worldSpacePosition = position;
gl_Position = modelViewProjectionMatrix * position;
}
// frag shader for writing depth
#version 330
// world space position of the fragment
in vec4 o_worldSpacePosition;
// distance that will be saved to framebuffer
out float resultingColor;
void main( void ) {
vec3 u_lightPos = vec3( 0.0, 0.0, 0.0 );
// distance from light to near and far cliping planes
vec2 u_nearFarPlane = vec2( 0.0, 1000.0 );
// additional offset from the light
float u_depthOffset = 0.0001;
// distance to light
float distanceToLight = distance( u_lightPos, o_worldSpacePosition.xyz);
// normalize distance taking into account near and far clipping planes
// so valid distances should be in [0, 1] range
resultingColor = (distanceToLight - u_nearFarPlane.x) / (u_nearFarPlane.y - u_nearFarPlane.x);// + u_depthOffset;
// clamp distances to [0, 1] range
resultingColor = clamp(resultingColor, 0.0, 1.0);
}