Я создаю объект framebuffer для рендеринга сцены в качестве значений глубины для рендеринга теневых карт, после инициализации сцены и компиляции всех шейдеров я добавляю направленный свет и создаю FBO, используя этот код:
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);
затем в цикле рендеринга я визуализирую сцену в сгенерированном кадровом буфере с помощью шейдера глубины, затем регулярно отрисовываю сцену на экране после отсоединения FBO, это код:
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);
первая функция, вызываемая перед циклом рендеринга, и FBO, сгенерированный и имеющий идентификатор, но проблема в том, что функция рендеринга проигнорировала его, хотя я связываю его с его идентификатором, который не является минусом или даже не нулем в той степени, в которой при удалении кода создать и настроить кадровый буфер, ничего не меняется в результате рендеринга, я в этой проблеме в течение недели!
Редактировать:
Вершинный шейдер для глубины:
#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;
}
renderDepth()
для каждой сетки с помощью программы глубинного шейдера:
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);
}
}
Задача ещё не решена.
Других решений пока нет …