【发布时间】:2014-07-22 16:41:44
【问题描述】:
使用立方体贴图时,我在着色器中得到不一致的结果,而不是在我的程序中。
出于测试目的,我编写了一个测试程序,它简单地创建一个深度立方体贴图纹理并将“1”写入它的所有边:
unsigned int frameBuffer;
glGenFramebuffers(1,&frameBuffer);
unsigned int texture;
glGenTextures(1,&texture);
glBindFramebuffer(GL_FRAMEBUFFER,frameBuffer);
glBindTexture(GL_TEXTURE_CUBE_MAP,texture);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_DEPTH_TEXTURE_MODE,GL_LUMINANCE);
glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_COMPARE_FUNC,GL_LEQUAL);
glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_COMPARE_MODE,GL_COMPARE_R_TO_TEXTURE);
unsigned int width = 512;
unsigned int height = 512;
for(unsigned int i=0;i<6;i++)
{
glTexImage2D(
GL_TEXTURE_CUBE_MAP_POSITIVE_X +i,
0,
GL_DEPTH_COMPONENT16,
width,height,
0,GL_DEPTH_COMPONENT,
GL_FLOAT,
0
);
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_TEXTURE_CUBE_MAP_POSITIVE_X +i,texture,0);
}
unsigned int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status != GL_FRAMEBUFFER_COMPLETE)
return;
float *data = new float[width *height];
for(unsigned long long i=0;i<(width *height);i++)
data[i] = 1.f;
for(unsigned int i=0;i<6;i++)
{
glTexSubImage2D(
GL_TEXTURE_CUBE_MAP_POSITIVE_X +i,
0,
0,
0,
width,height,
GL_DEPTH_COMPONENT,
GL_FLOAT,
&data[0]
);
}
delete[] data;
// Check to see if data has been written correctly
data = new float[width *height];
for(unsigned int i=0;i<6;i++)
{
glFramebufferTexture2D(GL_READ_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_TEXTURE_CUBE_MAP_POSITIVE_X +i,texture,0);
glReadPixels(0,0,width,height,GL_DEPTH_COMPONENT,GL_FLOAT,&data[0]);
for(unsigned long long j=0;j<(width *height);j++)
{
if(data[j] != 1.f)
return;
}
}
delete[] data;
// Check end
渲染:
float screenVerts[18] = {
-1.f,-1.f,0.f,
1.f,-1.f,0.f,
-1.f,1.f,0.f,
-1.f,1.f,0.f,
1.f,-1.f,0.f,
1.f,1.f,0.f
};
unsigned int vertexBuffer;
glGenBuffers(1,&vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER,vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(float) *18,&screenVerts[0],GL_STATIC_DRAW);
glUseProgram(shader);
glBindTexture(GL_TEXTURE_CUBE_MAP,texture);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER,vertexBuffer);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);
glDrawArrays(GL_TRIANGLES,0,6);
glDisableVertexAttribArray(0);
顶点着色器:
#version 330 core
layout(location = 0) in vec3 vertPos;
out vec2 UV;
void main()
{
gl_Position = vec4(vertPos,1);
UV = (vertPos.xy +vec2(1,1)) /2.0;
}
片段着色器:
#version 330 core
in vec2 UV;
out vec3 color;
uniform samplerCubeShadow testShadow;
void main()
{
color.r = texture(testShadow,vec4(0,0,1,1));
// Just grab the value from a random direction and put it out as red color
}
(我已经从另一种语言中移植了 C++ 代码,所以如果您发现其中有一些语法错误,请不要介意,它们不在实际代码中)
glGetError() 不返回任何错误。
ReadPixels 证明写入过程有效,但结果是黑屏。这意味着着色器内部的纹理调用返回 0,无论我使用什么作为方向向量,这应该是不可能的。
我错过了什么?
【问题讨论】:
-
离题了,但您可以从 VBO 中删除 Z=0 列,因为它显然没有在那里使用,从而为您节省几个字节的视频内存。
-
另外,使用 VAO 和 drawElements 可以节省更多空间和 vram 访问权限。