Android平台OpenGL ES开发调用glCreateShader()方法崩溃问题求助
问题根因定位
glCreateShader 调用崩溃90%以上的场景是OpenGL ES 上下文未正确初始化,或调用线程不是GL专属线程,按以下优先级排查即可:
1. 检查GLSurfaceView基础配置
你用的是GLES20的API,必须在给GLSurfaceView设置Renderer之前指定OpenGL版本,漏写这行一定会触发崩溃:
// 在你的Fragment中初始化GLSurfaceView时添加这行,必须在setRenderer之前调用 glSurfaceView.setEGLContextClientVersion(2); glSurfaceView.setRenderer(new OpenGLRenderer());
2. 检查Manifest声明
在AndroidManifest.xml的<manifest>标签下添加OpenGL ES 2.0的版本声明:
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
3. 确认GL API调用线程
所有GLES20.xxx开头的API,必须在GL线程执行,不能在Fragment的主线程(如onCreate/onCreateView回调)中调用:
- 你的
Triangle初始化逻辑里调用了loadShader,必须保证new Triangle()的操作只在Renderer的onSurfaceCreated回调中执行,该回调是GL上下文就绪后在GL专属线程触发的 - 禁止在主线程直接调用
loadShader、glCreateProgram等GL API
4. 绑定GLSurfaceView生命周期
在Fragment的生命周期回调中同步GLSurfaceView的状态,避免GL上下文被销毁后调用API:
@Override public void onResume() { super.onResume(); glSurfaceView.onResume(); } @Override public void onPause() { super.onPause(); glSurfaceView.onPause(); }
5. 补充GL错误检查
可以在GL API调用后添加错误日志,方便定位具体问题,修改后的loadShader参考:
public static int loadShader(int type, String shaderCode) { int shader = GLES20.glCreateShader(type); // 检查创建错误 int error = GLES20.glGetError(); if (error != GLES20.GL_NO_ERROR) { Log.e("OpenGL", "创建Shader失败,错误码:0x" + Integer.toHexString(error)); return 0; } GLES20.glShaderSource(shader, shaderCode); GLES20.glCompileShader(shader); // 检查编译状态 int[] compileStatus = new int[1]; GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compileStatus, 0); if (compileStatus[0] == 0) { Log.e("OpenGL", "Shader编译失败:" + GLES20.glGetShaderInfoLog(shader)); GLES20.glDeleteShader(shader); return 0; } return shader; }
问题解决后记得恢复loadShader中被注释的代码,不要直接返回0,否则后续Shader绑定到Program时也会出错。
内容的提问来源于stack exchange,提问作者YourRentIsDue
相关产品推荐
相关产品推荐

