2016-11-26 178 views
1

所以我一直试图让阴影映射工作,但我没有成功,我现在试图简单地写任何东西到帧缓冲区,然后将其渲染为四边形作为纹理。我一直在看这个小小的代码10个小时,所以我认为它可能最终是时候寻求一些帮助。如果您需要更多信息或者有什么不清楚的地方,请告诉我。OpenGL - 无法写入帧缓冲区(或正确读取它)

我开始按照这个tutorial。完成两次后,直接拷贝第三次粘贴,我放弃了,并开始寻找其他信息。我目前的代码有点乱,但我试图提取什么是关键

这是我如何设置我的FBO与TEXTURE2D(_shadowMap和_shadowMapFBO是作为主程序的类中的私有变量) :

glGenTextures(1, &_shadowMap); 
glBindTexture(GL_TEXTURE_2D, _shadowMap); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); 

glGenFramebuffers(1, &_shadowMapFBO); 
glBindFramebuffer(GL_FRAMEBUFFER, _shadowMapFBO); 
glDrawBuffer(GL_NONE); 
glReadBuffer(GL_NONE); 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _shadowMap, 0); 
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 
{ 
    std::cout << "Frame buffer failed" << std::endl; 
    system("pause"); 
    exit(1); 
} 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 

我然后做第一个呈现在主回路通:

glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT); 
glBindFramebuffer(GL_FRAMEBUFFER, _shadowMapFBO); 
glClear(GL_DEPTH_BUFFER_BIT); 
_shadowShader.bind(); 
glBindVertexArray(_cubeVAO); 
glDrawElements(GL_TRIANGLES, _numberOfIndicesCube, GL_UNSIGNED_SHORT, 0); 
glBindVertexArray(_planeVAO); 
glDrawElements(GL_TRIANGLES, _numberOfIndicesPlane, GL_UNSIGNED_SHORT, 0); 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 
glDrawBuffer(GL_BACK); 
glReadBuffer(GL_BACK); 

起初,我想创造一个阴影贴图,但在这一点上,我只是想写一个明确的价值到使用以下阴影附加到帧缓冲区的整个纹理

glViewport(0, 0, _screenWidth, _screenHeight); 
glClearColor(0.7f, 0.5f, 0.0f, 1.0f); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
_testShader.bind(); 
glBindTexture(GL_TEXTURE_2D, _shadowMap); 
glBindVertexArray(_quadVAO); 
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); 

,R对(由_shadowShader使用的)

顶点

#version 450 

in layout(location=0) vec3 position; 

uniform mat4 mvp; 

void main() 
{ 
    gl_Position = mvp * vec4(position, 1.0f); 
} 

片段

#version 450 

out float depth; 

void main() 
{ 
    depth = 0.0f; 
} 

我然后试图通过在四显示纹理完成了以下是四元素的片段着色器:

#version 450 

in vec2 textureCoordinates; 

uniform sampler2D _shadowMap; 

out vec4 color; 

void main() 
{ 
    float depth = texture2D(_shadowMap, textureCoordinates).r; 
    color = texture2D(_shadowMap, textureCoordinates); 
} 

但是对于我不断的沮丧,虽然我从片段着色器中输出0.0f(黑色),但四边形显示为白色...我知道四边形能够显示纹理,因为我已经能够渲染正常纹理上显示一个.jpg。所以,这就是我现在所处的位置;任何想法,指针,想法,激励性文字等?

编辑我:所以经过一段时间后,我至少弄清楚纹理加载正确,并且能够从中读取。我通过在初始化过程中实际加载一个映像来完成此操作,然后不写入它。四边形然后正确显示纹理。所以我写这封信的方式肯定有问题。

编辑二:所以我得到它的工作;我坐下来用电讯管理局复制粘贴的代码(是的,我知道...并没有比这更好),它现在可以工作。由于巴特:)

回答

0

你的身影通片段着色器是错误的:

#version 450 

out float depth; 

void main() 
{ 
    depth = 0.0f; 
} 

这不只是声明了一个单信道颜色输出,这将被写入附色(你不有)。由于您想写入FBO的深度附件,因此必须使用内置的gl_FragDepth输出变量。如果您不这样做,则GL会将线性内插窗口空间深度值写入深度缓冲区。

请注意,通常情况下,您将深度缓冲区清除为1.0,并且在使用典型的透视投影时,您的对象看起来会非常接近1.0,例如0.99的某处作为深度值,因此很可能转换结果只有8位灰度将看起来全白。

+0

感谢您的回复;所以我确实得到它的工作,正准备写出来。我确实尝试了你的建议,做了gl_fragDepth = 0.2f,但这也没有奏效(这是我在此发布之前)。我从我的一个助手那里得到了一些帮助,出于某种原因,他坐在我身边,复制粘贴了它所用的教程的代码。不管怎么说,还是要谢谢你 :) – MulattoKid