C++ 尝试采样立方体贴图纹理时,GL_无效_操作

C++ 尝试采样立方体贴图纹理时,GL_无效_操作,c++,opengl,3d,glsl,framebuffer,C++,Opengl,3d,Glsl,Framebuffer,我正在使用这个过程进行阴影投射,我们将场景渲染到一个帧缓冲区,附加一个立方体贴图来保存深度值。然后,我们将这个立方体贴图传递给片段着色器,片段着色器对其进行采样并从中获取深度值 我与教程略有不同,我没有使用几何体着色器一次渲染整个立方体贴图,而是渲染了六次场景以获得相同的效果,这主要是因为我当前的着色器系统不支持几何体着色器,目前我不太关心性能的影响 深度立方体贴图正在绘制中,以下是gDEBugger的屏幕截图: 这里似乎一切都井然有序 然而,当我尝试对这个立方体贴图进行采样时,我的片段着色器

我正在使用这个过程进行阴影投射,我们将场景渲染到一个帧缓冲区,附加一个立方体贴图来保存深度值。然后,我们将这个立方体贴图传递给片段着色器,片段着色器对其进行采样并从中获取深度值

我与教程略有不同,我没有使用几何体着色器一次渲染整个立方体贴图,而是渲染了六次场景以获得相同的效果,这主要是因为我当前的着色器系统不支持几何体着色器,目前我不太关心性能的影响

深度立方体贴图正在绘制中,以下是gDEBugger的屏幕截图:

这里似乎一切都井然有序

然而,当我尝试对这个立方体贴图进行采样时,我的片段着色器出现了问题。在调用
glDrawArrays
之后,调用
glGetError
返回
GL\u INVALID\u OPERATION
,据我所知,它来自这里:(有问题的行已注释)

注释掉上面提到的行似乎可以让一切正常工作-所以我假设是对纹理采样器的调用导致了问题。-但根据格德布格的说法,情况并非如此:

纹理16是深度立方体贴图

如果相关的话,以下是我如何设置FBO:(只打过一次电话)

//生成帧缓冲区
glGenFramebuffers(1,&depthMapFrameBuffer);
//生成深度贴图
glGenTextures(1和depthMap);
//设置纹理
玻璃纹理(GL_纹理0);
glBindTexture(GL_纹理_立方体_贴图,深度贴图);
对于(int i=0;i<6;++i)
GLTEXAGE2D(GL_纹理_立方体_贴图_正X+i,0,GL_深度_分量,
ShadowmapSize,ShadowmapSize,0,总图深度分量,总图浮点,NULL);
//设置纹理参数
glTexParameteri(GL_纹理\立方体\贴图,GL_纹理\图像\过滤器,GL_最近);
glTexParameteri(GL_纹理\立方体\贴图,GL_纹理\最小\过滤器,GL_最近);
glTexParameteri(GL_纹理\立方体\贴图、GL_纹理\包裹\ S、GL_夹紧\ u到\ u边);
glTexParameteri(GL_纹理\立方体\贴图、GL_纹理\包裹\ T、GL_夹紧\ U到\ U边);
glTexParameteri(GL_纹理\立方体\贴图、GL_纹理\包裹\ R、GL_夹紧\至\边缘);
//将立方体贴图连接到FBO
glBindFramebuffer(GL_FRAMEBUFFER,depthMapFrameBuffer);
glFramebufferTexture(GL_帧缓冲区,GL_深度_附件,深度贴图,0);
glDrawBuffer(无GLU);
glReadBuffer(GL_NONE);
如果(glCheckFramebufferStatus(GL\U FRAMEBUFFER)!=GL\U FRAMEBUFFER\U COMPLETE)
错误日志(“PointLight创建的帧缓冲区不完整!\n”);
glBindTexture(GL_纹理_立方体_贴图,0);
glBindFramebuffer(GL_帧缓冲区,0);
下面是我用它画画的方式:(称为每一帧)

//设置视口
glViewport(0,0,ShadowmapSize,ShadowmapSize);
//绑定帧缓冲区
glBindFramebuffer(GL_FRAMEBUFFER,depthMapFrameBuffer);
//清除深度缓冲区
glClear(GLU深度缓冲位);
//渲染场景
对于(int i=0;i<6;++i)
{
sh->SetUniform(“阴影矩阵”,lightSpaceTransforms[i]);
glFramebufferTexture2D(GLU帧缓冲区、GLU深度附件、,
GL_纹理_立方体_贴图_正片_X+i,深度贴图,0);
Space()->Get()->RenderScene(sh);
}
//解绑帧缓冲器
glBindFramebuffer(GL_帧缓冲区,0);
下面是我在画画之前是如何装订的:

std::stringstream ssD;
ssD << "PointLights[" << i << "].DepthMap";
glActiveTexture(GL_TEXTURE4 + i);
glBindTexture(GL_TEXTURE_CUBE_MAP, pointlights[i]->DepthMap()); // just returns the ID of the light's depth map
shader->SetUniform(ssD.str().c_str(), i + 4); // just a wrapper around glSetUniform1i
std::stringstream ssD;

ssD这是一篇老文章,但我认为它可能对搜索中的其他人有用。 你的问题在这里:

glActiveTexture(GL_TEXTURE4 + i);
glBindTexture(GL_TEXTURE_CUBE_MAP, pointlights[i]->DepthMap()); 
此替换应修复以下问题:

glActiveTexture(GL_TEXTURE4 + i);
glUniform1i(glGetUniformLocation("programId", "cubMapUniformName"), GL_TEXTURE4 + i);

glBindTexture(GL_TEXTURE_CUBE_MAP, pointlights[i]->DepthMap()); 

它为着色器采样器设置纹理单元编号

您的错误可能与您在片段着色器中所说的一样。编译着色器后,请使用
glGetShaderInfoLog
函数,让我们查看着色器编译错误。很抱歉,在OP中忘了提到这一点。在编译片段和顶点着色器后,我确实已经调用了glGetShaderInfoLog,链接后我调用了glGetProgramInfoLog——看起来着色器编译和链接时没有警告或错误。“它为着色器采样器设置纹理单元编号”。否,将“采样器统一”设置为某个GL enum值,但它需要使用纹理单元的从零开始的索引。
std::stringstream ssD;
ssD << "PointLights[" << i << "].DepthMap";
glActiveTexture(GL_TEXTURE4 + i);
glBindTexture(GL_TEXTURE_CUBE_MAP, pointlights[i]->DepthMap()); // just returns the ID of the light's depth map
shader->SetUniform(ssD.str().c_str(), i + 4); // just a wrapper around glSetUniform1i
glActiveTexture(GL_TEXTURE4 + i);
glBindTexture(GL_TEXTURE_CUBE_MAP, pointlights[i]->DepthMap()); 
glActiveTexture(GL_TEXTURE4 + i);
glUniform1i(glGetUniformLocation("programId", "cubMapUniformName"), GL_TEXTURE4 + i);

glBindTexture(GL_TEXTURE_CUBE_MAP, pointlights[i]->DepthMap());