GLES3多纹理异常:仅GL_TEXTURE0纹理可绘制问题求助
GLES3多纹理仅GL_TEXTURE0生效问题解决方案
核心问题
你在设置sampler2D类型的uniform时,错误使用了glUniform1ui(无符号整数),而GLSL中采样器要求有符号整数赋值,类型不匹配触发OpenGL错误,导致采样器始终默认使用0号纹理槽。
修复步骤
1. 替换uniform设置的函数
将所有针对sampler2D的glUniform1ui调用替换为glUniform1i:
- 修改初始化代码中的行B:
// 原错误代码 // GLES30.glUniform1ui(locc, 1); // 改为 GLES30.glUniform1i(locc, 1); - 更新
ShaderProgram中的uniform设置方法(新增/修改为有符号整数版本):void setUniform1i(String name, int data) { int locc = GLES30.glGetUniformLocation(id, name); if (locc == -1){ Log.e("UniformError", "Uniform not found: " + name); } GLES30.glUniform1i(locc, data); } - 调用时使用这个新方法:
shader.setUniform1i("m_texture", ts2.slot);
2. 确保纹理激活与绑定的正确性
在绘制前重新绑定纹理(避免其他操作覆盖绑定状态),修改Texture类的activeToShader方法:
public void activeToShader(ShaderProgram sp, String nume){ GLES30.glActiveTexture(GLES30.GL_TEXTURE0 + slot); GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, id[0]); // 补充绑定步骤 sp.setUniform1i(nume, slot); }
验证方式
修改后初始化纹理到槽1并调用激活方法:
ts2 = new Texture(getBaseContext(), "apple.png", 1); ts2.activeToShader(shader, "m_texture");
此时片段着色器就能正确采样槽1中的纹理,不会再出现黑屏。
关键规范说明
- OpenGL明确要求:
sampler2D等采样器类型的uniform,必须通过glUniform1i/glUniform1iv设置,因为采样器索引是有符号整数类型,无符号整数赋值会触发GL_INVALID_OPERATION错误(也就是你用glGetError查到的问题)。 - 你测试的
thing是float类型,用setUniform1ui能生效是因为OpenGL做了隐式类型转换,但采样器类型不支持这种转换,必须严格匹配。
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

