出于某种原因,在我的android程序中调用onPause时,Opengl es会崩溃。 (是否通过旋转或后退按钮/主页按钮被按下。) 我做了一堆调试,并确定问题的原因与未卸载的着色器有关。但是,我尝试手动卸载它们仍然会崩溃。这是我的程序的精简版本,可用于重新创建错误。 任何帮助解决这个问题的人都表示赞赏。
public class MainActivity extends Activity implements GLSurfaceView.Renderer {
private int program;
private int vertexShader;
private int fragmentShader;
private int texture;
private GLSurfaceView glView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
glView= new GLSurfaceView(this);
glView.setEGLContextClientVersion(2);
glView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
glView.setRenderer(this);
setContentView(glView);
}
@Override
protected void onPause() {
super.onPause();
glView.onPause();
}
@Override
protected void onResume() {
super.onResume();
glView.onResume();
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GLES20.glClearColor(0, 0, 0, 1);
String VertexShaderSource=...//See vertex shader code
String FragmentShaderSource=...//See fragment shader code
//Compile vertex shader.
vertexShader= GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
GLES20.glShaderSource(vertexShader,VertexShaderSource);
GLES20.glCompileShader(vertexShader);
String vCompileLog=GLES20.glGetShaderInfoLog(vertexShader);
//Compile fragment shader.
fragmentShader=GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
GLES20.glShaderSource(fragmentShader,FragmentShaderSource);
GLES20.glCompileShader(fragmentShader);
String fCompileLog=GLES20.glGetShaderInfoLog(fragmentShader);
//Link shaders
program=GLES20.glCreateProgram();
GLES20.glAttachShader(program,vertexShader);
GLES20.glAttachShader(program,fragmentShader);
GLES20.glBindAttribLocation(program, 0, "position");
GLES20.glBindAttribLocation(program,1,"textureCoordinate");
GLES20.glLinkProgram(program);
String programLinkLog=GLES20.glGetProgramInfoLog(program);
GLES20.glUseProgram(program);
//Enable textures, and load a texture to memory.
GLES20.glEnable(GLES20.GL_TEXTURE_2D);
Bitmap bmptexture= BitmapFactory.decodeResource(getResources(), R.drawable.texture); //Load the bitma
IntBuffer textureID=IntBuffer.allocate(1); //Create a textureID buffer.
GLES20.glGenTextures(1,textureID); //Generate an Id for the texture.
texture=textureID.get(0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,textureID.get(0));
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_LINEAR);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmptexture, 0);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
//..Note that setting up the glviewport here doesn't solve the problem.
}
@Override
public void onDrawFrame(GL10 gl) {
//see onDraw code
}
}
片段着色器:
FragmentShaderSource="" +
"uniform sampler2D textureUnit;"+
"varying highp vec2 textureCoordinateVarying;"+
"void main()"+
"{"+
"vec4 color=texture2D(textureUnit,textureCoordinateVarying);"+
"gl_FragColor=color;"+
"}";
顶点着色器:
VertexShaderSource=""+
"uniform vec3 translate;"+
"attribute vec4 position;"+
"attribute vec2 textureCoordinate;"+
"varying vec2 textureCoordinateVarying;"+
"void main()"+
"{"+
" gl_Position= position + vec4(translate.x,translate.y,translate.z,0.0);"+
" textureCoordinateVarying=textureCoordinate;"+
"}";
onDraw代码:
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
float destPoints[]={
0,0,0,1.0f,
0,1,0,1.0f,
1,0,0,1.0f,
1,0,0,1.0f,
0,1,0,1.0f,
1,1,0,1.0f,
};
float srcPoints[]={
0,0,
0,1,
1,0,
1,0,
0,1,
1,1,
};
ByteBuffer BBDestBuffer=ByteBuffer.allocateDirect(destPoints.length*4);
ByteBuffer BBSrcBuffer=ByteBuffer.allocateDirect(srcPoints.length*4);
FloatBuffer vDestBuffer;
FloatBuffer vSrcBuffer;
BBDestBuffer.order(ByteOrder.nativeOrder());
BBSrcBuffer.order(ByteOrder.nativeOrder());
vDestBuffer=BBDestBuffer.asFloatBuffer();
vSrcBuffer=BBSrcBuffer.asFloatBuffer();
int TranslateDrawingLocation=GLES20.glGetUniformLocation(program,"translate");
GLES20.glUniform3f(TranslateDrawingLocation, 0, 0, 0);
int TranslateTextureLocation=GLES20.glGetUniformLocation(program,"textureUnit");
GLES20.glUniform1i(TranslateTextureLocation,0);
vDestBuffer.put(destPoints);
vDestBuffer.position(0);
vSrcBuffer.put(srcPoints);
vSrcBuffer.position(0);
GLES20.glEnableVertexAttribArray(0);
GLES20.glVertexAttribPointer(0, 4, GLES20.GL_FLOAT, false, 4 * 4, vDestBuffer);
GLES20.glEnableVertexAttribArray(1);
GLES20.glVertexAttribPointer(1, 2, GLES20.GL_FLOAT, false, 4 * 2, vSrcBuffer);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0,6 );
以下是logcat日志(没有GLES内存转储):
11-26 02:54:03.373 280-417 / system_process W / ActivityManager:强制删除ActivityRecord {40e7a8a0 u0 com.tests.simpleegl2 / .MainActivity}:app死亡,没有保存状态
11-26 02:54:03.401 280-909 / system_process I / WindowState:WIN DEATH:Window {4138cb70 u0 com.tests.simpleegl2 / com.tests.simpleegl2.MainActivity}
11-26 02:54:03.401 280-909 / system_process W / WindowManager:从容器窗口强制删除子窗口{40f67860 u0 SurfaceView} {4138cb70 u0 com.tests.simpleegl2 / com.tests.simpleegl2.MainActivity }
11-26 02:54:03.421 280-312 / system_process E / InputDispatcher:接收未知输入通道的杂散接收回调。 fd = 204,事件= 0x9
11-26 02:54:03.441 280-481 / system_process W / WindowManager:查找窗口失败 java.lang.IllegalArgumentException:请求的窗口android.os.BinderProxy@40ebb0e8不存在 在com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:8102) 在com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:8093) 在com.android.server.wm.WindowState $ DeathRecipient.binderDied(WindowState.java:932) 在android.os.BinderProxy.sendDeathNotice(Binder.java:433) 在dalvik.system.NativeStart.run(原生方法)
11-26 02:54:03.441 280-481 / system_process I / WindowState:WIN DEATH:null
编辑:奇怪的是,在顶点着色器中改变变化的vec2 textureCoordinateVarying; 到变化的highp vec2 textureCoordinateVarying; 似乎已经解决了这个问题。 **至少在我的手机上,模拟器仍然崩溃。放弃模拟器,因为它毫无价值。