Android: GLSurfaceView становится черным после возобновления работы приложения - PullRequest
4 голосов
/ 18 ноября 2011

Согласно заголовку, 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");
}

У меня естьпрочитайте, что вам нужно воссоздать контекст GL внутри onSurfaceChanged, но я не уверен, как, или если я уже сделал, когда вызывался onSurfaceCreated.

Пожалуйста, помогите!

Редактировать: Вот код onResume из Activity, который содержит GLSurfaceView: (здесь он называется 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();
}

Я мало что сделал в onResume для GLSurfaceView и не нашеллюбая документация, которая предполагает, что мне нужно сделать что-либо, в частности, чтобы вернуть мой контекст EGL либо.

Edit 2: Я также хотел бы отметить, что вызов setPreserveEGLContextOnPause(true) в конструкторемой GLSurfaceView, к сожалению, не решил мою проблему.

Ответы [ 2 ]

5 голосов
/ 25 декабря 2012

setPreserveEGLContextOnPause (true) поддерживается только на устройствах с Android 3.X и выше.(даже тогда это зависит от устройства, поддерживается ли оно)

Решение, которое вы ищете, заключается в родительской активности GlSurfaceView, которую вы вызываете GlSurfaceView.onPause () в методе onPause действия и GlSurfaceView.onResume () в методе действия onResume.

Обратите внимание, что это приводит к потере всех ваших текстур и буферов.Вам нужно перезагрузить их в этот момент.

0 голосов
/ 02 декабря 2011

Это немного, но вы пытаетесь контролировать ориентацию или изменения конфигурации (т. Е. У вас есть public void onConfigurationChanged(Configuration config) в переопределении вашей активности)?

Я обнаружил, что если у меня onConfigurationChanges() переопределено в моей активности и android:screenOrientation="landscape" в моем файле манифеста, но не android:configChanges="orientation", я получаю что-то похожее на то, что вы описываете

...