Я создаю простую сцену с направленным светом. Моя цель — создать тени сцены с помощью картирования теней. Я искал помощь по этой теме, но безрезультатно. Насколько я могу судить, мой код должен быть эквивалентен тому, что я видел в нескольких уроках.
Сцена создана идеально, просто без теней. Я подозреваю, что это проблема с текстурой карты теней, которая генерируется (или нет) в первом проходе моей программы рендеринга. Когда я рисую визуализированную текстуру на четырехугольнике, четырехугольник становится белым.
Мой код инициализации буфера / текстуры выглядит так:
void Renderer :: initBuffers()
{
glGenTextures(1, &SMDepthTexture);
glBindTexture(GL_TEXTURE_2D, SMDepthTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE );
glTexParameteri( GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE );
glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glBindTexture(GL_TEXTURE_2D, 0);
/*
glGenRenderbuffers(1, &SMRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, SMRenderBuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, SMRenderBuffer);
*/
glGenFramebuffers(1, &SMFrameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, SMFrameBuffer);
glDrawBuffer(GL_NONE); // No color buffer is drawn to.
glReadBuffer(GL_NONE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, SMDepthTexture, 0);// Always check that our framebuffer is ok
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
std :: cerr << "Frame Buffer Status: " << glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) <<"\n";
exit(0);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
Моя функция отображения. (Pass = 1, если (pass == 1) материал кажется немного избыточным, но это было для отладки).
void Renderer :: displayCallback()
{
pass = 1;
if(pass == 1)
{
glMatrixMode(GL_PROJECTION);
gluPerspective(FOV,aspect,zNear, zFar);
glDisable(GL_TEXTURE_2D);
glBindFramebuffer(GL_FRAMEBUFFER, Renderer :: SMFrameBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, Renderer :: SMDepthTexture, 0);
glUseProgram(0);
glViewport(0,0,width,height);
glClear(GL_DEPTH_BUFFER_BIT);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
display();
}
pass = 2;
if(pass == 2)
{
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0,0,width,height);
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glUseProgram(Renderer :: shader_program_pass2);
Renderer :: uniforms2();
Renderer :: SMDepthTexture_handle = glGetUniformLocation(Renderer :: shader_program_pass2, "shadowMap");
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE7);
glBindTexture(GL_TEXTURE_2D, Renderer :: SMDepthTexture);
glUniform1i(Renderer :: SMDepthTexture_handle, 7);
display();
}
drawMap();
glutSwapBuffers();
}
Наконец, я пытаюсь нарисовать текстуру для заполнения экрана с помощью следующей функции:
void Renderer :: drawMap()
{
Renderer :: camera_modelview = Globals::camera.getInverseCM();
Renderer :: light_modelview = Renderer :: light_cam.getInverseCM();
if(pass == 1)
{
glLoadMatrixd(Renderer :: light_cam.getInverseCMGLPointer());
//glUniformMatrix4fv(Renderer :: camera_modelview_handle_pass1, 1, false, Renderer :: camera_modelview.getGLfloatPointer());
//glUniformMatrix4fv(Renderer :: light_modelview_handle_pass1, 1, false, Renderer :: light_modelview.getGLfloatPointer());
}
else if(pass == 2)
{
glUniformMatrix4fv(Renderer :: camera_modelview_handle_pass2, 1, false, Renderer :: camera_modelview.getGLfloatPointer());
glUniformMatrix4fv(Renderer :: light_modelview_handle_pass2, 1, false, Renderer :: light_modelview.getGLfloatPointer());
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glUseProgram(0);
glDisable(GL_LIGHTING);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-width/2,width/2,-height/2,height/2,1,20);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor4f(1,1,1,1);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,Renderer :: SMDepthTexture);
glEnable(GL_TEXTURE_2D);
glTranslated(0,0,-1);
glBegin(GL_QUADS);
glTexCoord2d(0,0);glVertex3f(-width/2,-height/2,0);
glTexCoord2d(1,0);glVertex3f(width/2,-height/2,0);
glTexCoord2d(1,1);glVertex3f(width/2,height/2,0);
glTexCoord2d(0,1);glVertex3f(-width/2,height/2,0);
glEnd();
glDisable(GL_TEXTURE_2D);
glLoadIdentity();
glEnable(GL_LIGHTING);
}
Я знаю, что проблема в том, что у многих людей возникает одна и та же текстура, связанная как с кадровым буфером, так и с активной текстурой одновременно. Я почти уверен, что избежал этого обстоятельства.
Я буду более чем рад опубликовать больше кода (включая шейдеры), если потребуется больше деталей. Я ценю вашу помощь, поэтому спасибо заранее!
Задача ещё не решена.