Due to the problems we’re having with debugging this, I’m going to show my code so that if I am missing anything you can let me know.
The cube map depth texture is initialized like this:
void ShadowCube::Init(){
cubeMapBuffer.genTexture();
glBindTexture(GL_TEXTURE_CUBE_MAP, cubeMapBuffer.getID());
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
for(int i = 0; i < 6; i++)
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0,
GL_DEPTH_COMPONENT32, shadowMapW, shadowMapH, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
frameBuff.genFBO();
glBindFramebuffer(GL_FRAMEBUFFER, frameBuff.getID());
for(int i = 0; i < 6; i++){
glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, cubeMapBuffer.getID(), 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
frameBuff.checkFBO();
}
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDrawBuffer(GL_BACK);
glReadBuffer(GL_BACK);
}
checkFBO outputs FBO errors. This set of texparamters purposely removes the mipmaps. Then it procedurally works through checking the cube map faces and making sure they can be attached to the FBO.
So after all that’s done, it’s updated like this:
struct CameraDirection
{
GLenum CubemapFace;
glm::vec3 Target;
glm::vec3 Up;
};
static const CameraDirection CameraDirections[6] =
{
{ GL_TEXTURE_CUBE_MAP_POSITIVE_X, glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f) },
{ GL_TEXTURE_CUBE_MAP_NEGATIVE_X, glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f) },
{ GL_TEXTURE_CUBE_MAP_POSITIVE_Y, glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f) },
{ GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f) },
{ GL_TEXTURE_CUBE_MAP_POSITIVE_Z, glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f) },
{ GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f) }
};
void ShadowCube::Update(glm::mat4){
GLint viewPort[4];
glGetIntegerv(GL_VIEWPORT, viewPort);
glViewport(0, 0, shadowMapW, shadowMapH);
glClearColor(FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX);
for(int i = 0; i < 6; i++){
glBindFramebuffer(GL_FRAMEBUFFER, frameBuff.getID());
glBindTexture(GL_TEXTURE_CUBE_MAP, cubeMapBuffer.getID());
viewProjectionMatrix = glm::perspective <float>(glm::radians(90.0f), shadowMapW / shadowMapH, 1.0f, 500.0f) * glm::lookAt(myCenterPos, myCenterPos + CameraDirections[i].Target, CameraDirections[i].Up);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, cubeMapBuffer.getID(), 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Grab current view before adjusting
glUseProgram(depthProgID.getID());
GLuint vpLoc = glGetUniformLocation(depthProgID.getID(), "depthVP");
glUniformMatrix4fv(vpLoc, 1, GL_FALSE, glm::value_ptr(viewProjectionMatrix));
glUseProgram(skelDepthProgID.getID());
vpLoc = glGetUniformLocation(skelDepthProgID.getID(), "VP");
glUniformMatrix4fv(vpLoc, 1, GL_FALSE, glm::value_ptr(viewProjectionMatrix));
DrawAllEntDepth();
frameBuff.checkFBO();
}
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(viewPort[0], viewPort[1], viewPort[2], viewPort[3]);
}
The FBO is bound along with the cube map texture. Then the texture is bound face by face to the FBO. The camera is set using the view and projection matrices, then it draws all of the objects in the scene using a simplified shader simply meant to draw it to a depth texture, so no colors. It seems to work fine, according to glReadPixels it does draw the depth geometry. I’ve dried calling glFrameBufferTexture2D to unbind the faces, but it still won’t sample from the texture.
Then after all of the shadow maps have been drawn, I bind them to the main render shader using this snippet:
void PointLight::Draw(ShaderObj* myProgID, int inShaderID){
glUseProgram(myProgID->getID());
pointShaderLightIDs* pIDs = pointIDs[myProgID];
glUniform3f(pIDs[inShaderID].colorID, color.x, color.y, color.z);
glm::vec3 myPosition = myTransform.getPosition();
glUniform3f(pIDs[inShaderID].posID, myPosition.x, myPosition.y, myPosition.z);
glUniform3f(pIDs[inShaderID].attenID, attenuation.x, attenuation.y, attenuation.z);
glUniform1i(pIDs[inShaderID].exID, 1);
glUniform1i(pIDs[inShaderID].shadSampID, inShaderID);
glUniform1i(pIDs[inShaderID].shadTexture, 10 + inShaderID);
dynamic_cast<ShadowCube*>(masterShadowMapList[inShaderID + MAX_LIGHTS])->myCenterPos = myTransform.getPosition();
dynamic_cast<ShadowCube*>(masterShadowMapList[inShaderID + MAX_LIGHTS])->Update(glm::mat4(1.0));
glUseProgram(myProgID->getID());
glActiveTexture(GL_TEXTURE0 + 10 + inShaderID);
glBindTexture(GL_TEXTURE_CUBE_MAP,
dynamic_cast<ShadowCube*>(masterShadowMapList[inShaderID + MAX_LIGHTS])->cubeMapBuffer.getID());
}
shadSampID determines which of the shadowCubes it reads from in the fragment shader. shadTexture tells it that the shadowCube will be bound to 10 + whatever id (0-3) it is on the point light list. The center position is given to help the f-shader to have a direction. The shadow cube is updated there, which is shown above. But then the active texture ID which was given to the sampler earlier is now given the actual cube map texture.
I hope at least some of this can help…I’m not sure where I went wrong, it’s not exactly a complicated set of concepts, you just bind the cube map’s faces to the framebuffer and draw each face in turn. I also made sure to check if the framebuffer was complete as I drew it before; it seems to be working on that front. Then it binds the cube map texture to the shader, then it’s sampled with the direction of the light to the fragment and it’s meant to return 0.0-1.0.
I’m going to try to run a working depth cube program in the meantime, but if you could take a quick peek through my code I’d appreciate it.