反射OpengGl es 2.0的立方体环境图(Android/Java)

反射OpengGl es 2.0的立方体环境图(Android/Java),android,reflection,graphics,opengl-es,opengl-es-2.0,Android,Reflection,Graphics,Opengl Es,Opengl Es 2.0,我已经阅读了很多关于反射环境映射的教程,其中一些教程是为立方体的每一侧创建一个帧缓冲区,另一些教程是为整个立方体使用一个帧缓冲区。哪种方法是正确的 我正在使用java和Android 4.0 我有以下代码,我得到了设置如下的glError 1282: glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + p_face, m_cubeMap[0], 0 ); 立

我已经阅读了很多关于反射环境映射的教程,其中一些教程是为立方体的每一侧创建一个帧缓冲区,另一些教程是为整个立方体使用一个帧缓冲区。哪种方法是正确的

我正在使用java和Android 4.0

我有以下代码,我得到了设置如下的glError 1282:

glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + p_face, m_cubeMap[0], 0 );
立方体贴图生成的代码是:

m_cubeMap = new int[1];
m_cubeFB  = new int[1];
m_cubeDB  = new int[1];
glGenTextures  ( 1, m_cubeMap, 0 );
glBindTexture  ( GL_TEXTURE_CUBE_MAP, m_cubeMap[0] );

glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,     GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,     GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR );      


glGenFramebuffers( 1, m_cubeFB, 0 );        
glBindFramebuffer( GL_FRAMEBUFFER, m_cubeFB[0] );

for( int i = 0; i < 6; i++ ) {
    glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, m_cubeMapSize, m_cubeMapSize, 0, GL_RGB, GL_UNSIGNED_BYTE, null );
}

glGenRenderbuffers   ( 1, m_cubeDB, 0 );
glBindRenderbuffer   ( GL_RENDERBUFFER, m_cubeDB[0] );
glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_cubeMapSize, m_cubeMapSize );

glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,  GL_RENDERBUFFER, m_cubeFB[0] );
glFramebufferTexture2D   ( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, m_cubeMap[0], 0 );

glBindFramebuffer ( GL_FRAMEBUFFER,      0 );    
glBindRenderbuffer( GL_RENDERBUFFER,     0 );
glBindTexture     ( GL_TEXTURE_CUBE_MAP, 0 );


if( LoggerConfig.ON )
    checkGlError( "InitRefCubeMap()" );
对于绘制每个面i,以及发生错误的位置:

glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + p_face, m_cubeMap[0], 0 );       
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

if( LoggerConfig.ON )
        checkGlError( "DrawRefCubeMap() Face " + p_face );


**更新** 另一个设备显示更好的调试信息。渲染时,我遇到以下着色器错误:
06-18 17:58:53.093:V/ShaderHelper(11910):日志:验证:采样器“u_立方体贴图”和“u_阴影贴图”的类型不同,但共享纹理单元0。

但是我对每个不同的纹理使用不同的纹理单位?如果我删除所有阴影贴图代码,它将显示另一个加载纹理的相同错误

**更新2**
在设置所有制服之前,我已验证着色器。更正后,错误不再出现。

GL\u INVALID\u操作错误很可能来自上一次调用:

glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                           GL_RENDERBUFFER, m_cubeFB[0] );
您使用的最后一个参数是帧缓冲区的名称,但必须是renderbuffer的名称。您需要将其更改为:

glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                           GL_RENDERBUFFER, m_cubeDB[0] );

缩小问题范围后,通常最好在可疑调用之前和之后放置
glGetError()
调用,以确认错误确实是由该调用触发的。

问题是,我在立方体贴图渲染和场景渲染中使用了相同的片段着色器。即使在立方体贴图渲染中未使用samplerCube(通过检查一致性),也会导致片段着色器崩溃。通过使用另一个没有立方体贴图采样器的更简单的片段着色器,它工作了


glError 1282 GL_INVALID_操作表示缺少frament着色器。

在阅读这些教程时,您是否将它们与桌面OpenGL混淆了?在OpenGL ES 2.0中,无法将分层图像附加到帧缓冲区对象,只能附加单个图像(例如,立方体贴图面或3D纹理的一个切片)。渲染到分层帧缓冲区需要几何体着色器,而ES没有几何体着色器,因此您必须一次执行一层的所有操作。此外,立方体贴图使用3D纹理坐标进行采样。。。您的换行模式目前仅适用于
S
T
。还有
R
,默认为
GL\u REPEAT
。很有可能您真的希望
R
GL\u夹紧到\u边缘
。谢谢您的回复。你所说的分层图像是什么意思?我试着一次写一次画到一边。我已尝试设置包裹模式,但GL_纹理_包裹R不可用。我不知道为什么…分层图像基本上是指具有多个图像的纹理。立方体贴图是其中之一,3D纹理和阵列纹理是其他类型。在ES 2.0中,您永远不能直接附加分层图像,而是始终必须从图像中精确附加一层。这是对您的陈述的回应:“在某些情况下,他们为多维数据集的每一侧创建一个帧缓冲区,而在其他情况下,他们为整个多维数据集使用一个帧缓冲区”。对整个立方体使用一个FBO的唯一方法是附加一个分层图像。不,您不必解除FBO的绑定。但是您必须更改绑定到
GL\u COLOR\u ATTACHMENT0
的层,这就是
glFramebufferTexture2D(GL\u FRAMEBUFFER,GL\u COLOR\u ATTACHMENT0,GL\u TEXTURE\u CUBE\u MAP\u POSITIVE\u X+p\u face,m\u cubeMap[0],0)
所做的(假设
p\u face
为0-5)。如果要绘制到不同的立方体面,则必须在每次绘制调用之间执行此操作。但如果使用碎片着色器中的以下代码访问3D纹理,则仍然会出现错误:
vec3 camRay=normalize((u_CameraCenter-u_CubeCenter)-(v_WorldPos-u_CubeCenter))
vec3 wNormal=正常化(v_WorldNormal)
vec3 reflection=textureCube(u_CubeMap,reflect(camRay,wNormal)).rgb
vec3折射=textureCube(u_立方贴图,折射(camRay,wNormal,1.1)).rgb我发现错误会发生在GL_纹理_立方体_贴图_正_X+1之后。第一张脸没有问题。我怀疑你可能在代码中做了一些没有显示出来的事情。例如,取消绑定FBO、删除FBO或删除立方体贴图纹理。使用参数从
glFramebufferTexture2D()
获取
GL\u无效\u操作
意味着没有绑定FBO,或者
m\u cubeMap[0]
不再是有效的立方体贴图纹理。我认为这是着色器问题?请看更新。
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                           GL_RENDERBUFFER, m_cubeDB[0] );