I create a framebuffer object to render scene as depth values to render shadow maps , after the scene initialized and all shaders compiled I add the directional light and create the FBO using this code:
glGenFramebuffers(1, &depthMapFBO);
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glGenTextures(1, &depthMap);
glBindTexture(GL_TEXTURE_2D, depthMap);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
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, depthMap, 0);
glDrawBuffers(1, GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
then in the render loop I render the scene on the generated framebuffer with the depth shader then render the scene again regularly on the screen after unbinding the FBO, this is the code :
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glClear(GL_DEPTH_BUFFER_BIT);
double delta = GetCurrentTime() - firstFrame;
glm::mat4 lightSpaceProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, -10.0f, 10.0f);
glm::mat4 lightSpaceView = glm::lookAt(-sun->direction, glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
lightSpaceMatrix = lightSpaceProjection * lightSpaceView;
directDepthShader.use();
GLuint lsm = glGetUniformLocation(directDepthShader.getProgramID(), "lightSpaceMatrix");
glUniformMatrix4fv(lsm, 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix));
for (mesh_it it = phongMeshes.begin(); it != phongMeshes.end(); it++) {
it->get()->renderDepth(directDepthShader, delta);
}
glCullFace(GL_BACK);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
the first function called before the rendering loop and the FBO generated and has an ID but the problem is the rendering function ignored it although I bind it with its ID which is not minus or even not zero to the extent that if I remove the code which create and adjust the framebuffer nothing changes in the rendering result, I am in that problem for a week !!
Edit:
Vertex shader for depth:
#version 300 es
precision mediump float;
layout (location = 0) in vec3 position;
layout (location = 4) in ivec4 BoneIDs;
layout (location = 5) in vec4 Weights;
const int MAX_BONES = 100;
uniform mat4 model;
uniform bool skinned;
uniform mat4 gBones[MAX_BONES];
uniform mat4 lightSpaceMatrix;
void main(){
vec4 nPos;
if(skinned){
mat4 BoneTransform = gBones[BoneIDs[0]] * Weights[0];
BoneTransform += gBones[BoneIDs[1]] * Weights[1];
BoneTransform += gBones[BoneIDs[2]] * Weights[2];
BoneTransform += gBones[BoneIDs[3]] * Weights[3];
nPos=BoneTransform * vec4(position, 1.0);
}
else
nPos = vec4(position, 1.0);
gl_Position = lightSpaceMatrix * model * nPos;
}
the renderDepth()
for each mesh using the the depth shader program:
void Mesh::renderDepth(Shader& shader, double& delta) {
if (isSkinned) {
glUniform1i(glGetUniformLocation(shader.getProgramID(), "skinned"), 1);
vector<Matrix4f> Transforms;
BoneTransform(delta, Transforms);
for (uint j = 0; j < Transforms.size(); j++) {
Transforms[j] = Transforms[j].Transpose();
GLuint bonesLoc = glGetUniformLocation(shader.getProgramID(), (const GLchar*) ("gBones[" + ToString(j) + "]").c_str());
glUniformMatrix4fv(bonesLoc, 1, GL_FALSE, (const GLfloat*) Transforms[j]);
}
}
for (uint i = 0; i < m_Entries.size(); i++) {
glUniformMatrix4fv(glGetUniformLocation(shader.getProgramID(), "model"), 1, GL_FALSE, glm::value_ptr(m_Entries[i].matrix));
glBindVertexArray(m_Entries[i].m_VAO);
glDrawElements(GL_TRIANGLES, m_Entries[i].NumIndices, GL_UNSIGNED_INT, NULL);
glBindVertexArray(0);
}
}