为什么调用GLES30.glUniformMatrix4fv会返回GL_INVALID_OPERATION错误
问题根因分析
- 着色器程序未激活就调用uniform赋值接口
glUniform*系列接口要求必须在对应着色器程序通过glUseProgram绑定到当前上下文之后才能调用。你在实例化StaticShader之后直接调用loadTRansformationMatrix,此时构造函数末尾已经调用了stop()将当前绑定程序重置为0,没有激活对应着色器程序,直接赋值就会触发GL_INVALID_OPERATION错误。 - uniform变量被编译器优化剔除
你的顶点着色器里虽然声明了uniform mat4 transformationMatrix,也计算了vec4 finalPos = transformationMatrix * position,但是最终gl_Position直接赋值为原始position,完全没有用到transformationMatrix的计算结果。GLSL编译器会自动优化剔除未实际影响输出的uniform变量,此时getUniformLocation("transformationMatrix")会返回无效值-1,你向无效的location赋值也会触发GL_INVALID_OPERATION错误。
修复方案
- 修正顶点着色器代码,将
gl_Position = position;改为gl_Position = finalPos;,确保transformationMatrix实际生效,避免被优化:
// 修改顶点着色器main函数逻辑 void main(){ UV = i_UV; color = position; vec4 finalPos = transformationMatrix * position; gl_Position = finalPos; // 替换原有的position赋值 }
- 调用uniform赋值接口前先激活对应着色器程序,修改实例化后的调用代码:
shader = new StaticShader(loader.loadAssetText("Shaders/Static.vertex"),loader.loadAssetText("Shaders/Static.fragment")); // 先激活着色器 shader.start(); shader.loadTRansformationMatrix(maths.createTransformationMatrix(new Vector3f(0.0f,0.0f,0.0f),new Vector3f(0.0f,0.0f,0.0f),new Vector3f(1.0f,1.0f,1.0f))); // 不需要使用该着色器时再调用shader.stop()
- 可在赋值uniform前额外加判断,避免给无效location赋值,减少不必要的报错:
public void loadUniformMatix(int location, Matrix4f matrix){ if(location < 0) return; // 无效location直接跳过 GLES30.glUniformMatrix4fv(location,1,false,matrix.mat,0); if(GLES30.glGetError() == GLES30.GL_INVALID_OPERATION) { Log.e("GLES Error2", "INVALID OPERATION"); } }
内容的提问来源于stack exchange,提问作者user14587078
相关产品推荐
相关产品推荐

