Android:恢复应用程序后 GLSurfaceView 变黑
根据标题,GLSurfaceView 从暂停状态恢复后为空白。渲染器的 onSurfaceCreated
、onSurfaceChanged
和 onDrawFrame
在恢复后被调用,但屏幕仍然是空白!
这是相关的代码:
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
boxWidth = 0.5f;
boxHeight = 0.5f;
boxCenter = new float[] { 0.5f, 0.5f };
Log.v("resume", "onSurfaceCreated");
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(0, 1, 0, 1, -5, 5);
gl.glMatrixMode(GL10.GL_MODELVIEW);
viewHeight = height;
viewWidth = width;
Log.v("resume", "onSurfaceChanged");
}
@Override
public void onDrawFrame(GL10 gl) {
gl.glLoadIdentity();
float halfW = boxWidth/2.0f;
float halfH = boxHeight/2.0f;
float left = Math.max(boxCenter[0]-halfW, 0.001f);
float right = Math.min(boxCenter[0]+halfW, 0.999f);
float top = Math.min(boxCenter[1]+halfH, 0.999f);
float bottom = Math.max(boxCenter[1]-halfH, 0.001f);
boxHeight = Math.max(top - bottom, 0.05f);
boxWidth = Math.max(right - left, 0.05f);
boxCenter[0] = left + boxWidth/2.0f;
boxCenter[1] = bottom + boxHeight/2.0f;
float vertices[] = {
left, top, 0.0f,
left, bottom, 0.0f,
right, bottom, 0.0f,
right, top, 0.0f
};
ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuf.asFloatBuffer();
vertexBuffer.put(vertices);
gl.glTranslatef(0.001f, -0.001f, -3.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT |
GL10.GL_DEPTH_BUFFER_BIT);
vertexBuffer.position(0);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vertexBuffer);
gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, 4);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
Log.v("resume", "drawing");
}
我读到您需要在 onSurfaceChanged 中重新创建 GL 上下文,但我不确定如何,或者在调用 onSurfaceCreated 时是否已经这样做了。
请帮忙!
编辑: 这是包含 GLSurfaceView 的 Activity 中的 onResume
代码:(此处称为 GLSurface)
public void onResume() {
super.onResume();
if (mGLSurface != null) {
if (mRenderer != null) {
float[] center = new float[2];
center[0] = settings.getFloat("renderer_boxCenter0", 0.5f);
center[1] = settings.getFloat("renderer_boxCenter1", 0.5f);
mRenderer.setBoxCenter(center);
mRenderer.setBoxWidth(settings.getFloat("renderer_boxWidth", 0.5f));
mRenderer.setBoxHeight(settings.getFloat("renderer_boxHeight", 0.5f));
}
mGLSurface.onResume();
}
我在 GLSurfaceView 的 onResume 中没有做太多事情,并且我没有找到任何建议我需要的文档做任何特别的事情来恢复我的 EGL 上下文。
编辑2: 不幸的是,我还想指出,在 GLSurfaceView 的构造函数中调用 setPreserveEGLContextOnPause(true) 并没有解决我的问题。
As per the title, the GLSurfaceView is blank after resuming from a paused state. The Renderer's onSurfaceCreated
, onSurfaceChanged
, and onDrawFrame
get called after it resumes, but the screen is still blank!
Here's the relevant code:
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
boxWidth = 0.5f;
boxHeight = 0.5f;
boxCenter = new float[] { 0.5f, 0.5f };
Log.v("resume", "onSurfaceCreated");
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(0, 1, 0, 1, -5, 5);
gl.glMatrixMode(GL10.GL_MODELVIEW);
viewHeight = height;
viewWidth = width;
Log.v("resume", "onSurfaceChanged");
}
@Override
public void onDrawFrame(GL10 gl) {
gl.glLoadIdentity();
float halfW = boxWidth/2.0f;
float halfH = boxHeight/2.0f;
float left = Math.max(boxCenter[0]-halfW, 0.001f);
float right = Math.min(boxCenter[0]+halfW, 0.999f);
float top = Math.min(boxCenter[1]+halfH, 0.999f);
float bottom = Math.max(boxCenter[1]-halfH, 0.001f);
boxHeight = Math.max(top - bottom, 0.05f);
boxWidth = Math.max(right - left, 0.05f);
boxCenter[0] = left + boxWidth/2.0f;
boxCenter[1] = bottom + boxHeight/2.0f;
float vertices[] = {
left, top, 0.0f,
left, bottom, 0.0f,
right, bottom, 0.0f,
right, top, 0.0f
};
ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuf.asFloatBuffer();
vertexBuffer.put(vertices);
gl.glTranslatef(0.001f, -0.001f, -3.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT |
GL10.GL_DEPTH_BUFFER_BIT);
vertexBuffer.position(0);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vertexBuffer);
gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, 4);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
Log.v("resume", "drawing");
}
I've read that you need to recreate the GL context inside onSurfaceChanged, but I'm not sure how, or if I already did when onSurfaceCreated was called.
Please help!
Edit:
Here's the onResume
code from the Activity that contains the GLSurfaceView: (called GLSurface here)
public void onResume() {
super.onResume();
if (mGLSurface != null) {
if (mRenderer != null) {
float[] center = new float[2];
center[0] = settings.getFloat("renderer_boxCenter0", 0.5f);
center[1] = settings.getFloat("renderer_boxCenter1", 0.5f);
mRenderer.setBoxCenter(center);
mRenderer.setBoxWidth(settings.getFloat("renderer_boxWidth", 0.5f));
mRenderer.setBoxHeight(settings.getFloat("renderer_boxHeight", 0.5f));
}
mGLSurface.onResume();
}
I didn't do much in the onResume for the GLSurfaceView, and I didn't find any documentation that suggested that I need to do anything in particular to get my EGL context back either.
Edit 2:
I would also like to note that calling setPreserveEGLContextOnPause(true)
in the constructor of my GLSurfaceView did not, unfortunately, solve my problem.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
setPreserveEGLContextOnPause(true)
仅在 Android 3.X 及更高版本的设备上受支持。 (即使如此,是否支持也取决于设备)
您寻找的解决方案是在 GlSurfaceView 的父活动中,您在活动的 onPause 方法中调用 GlSurfaceView.onPause() ,在 onResume 方法中调用 GlSurfaceView.onResume()活动。
请注意,这会导致所有纹理和缓冲区丢失。此时您需要重新加载它们。
setPreserveEGLContextOnPause(true)
is only supported on devices with Android 3.X and up. (even then it is device specific whether it is supported)
The solution your looking for is in the parent activity of the GlSurfaceView you call GlSurfaceView.onPause() in the onPause method of the activity and GlSurfaceView.onResume() in the onResume method of the activity.
Note this causes all of your textures and buffers to be lost. You need to reload them at this point.
这有点遥远,但是您是否尝试控制方向或配置更改(即您是否有
public void onConfigurationChanged(Configuration config)
覆盖您的活动)?我发现如果我在我的活动中重写了
onConfigurationChanges()
并在清单文件中重写了android:screenOrientation="landscape"
但没有重写android:configChanges="orientation “
我得到了类似于你所描述的内容This is a bit of a long shot, but do you try to control orientation or config changes (i.e. do you have
public void onConfigurationChanged(Configuration config)
in overridden your activity)?I found that if I have
onConfigurationChanges()
overriden in my activity andandroid:screenOrientation="landscape"
in my manifest file but notandroid:configChanges="orientation"
I get something like what you describe