Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Android OpenGL: relación de aspecto loco después de dormir

Si golpeo el botón de encendido en mi teléfono Android (o esperar a que el tiempo de espera) y el teléfono se va a dormir, después de despertar de nuevo, la relación de aspecto de la pantalla es todo fuera de mal.

Capturas de pantalla:

roto

Http://i.imgur.com/4C6ID.png

correcto

Http://i.imgur.com/CNAV0.png

En GameActivity.onCreate ()

// Grab display info DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); ACTUAL_SCREEN_WIDTH = (int) dm.widthPixels; ACTUAL_SCREEN_HEIGHT = (int) dm.heightPixels; ACTUAL_DENSITY = dm.density; double scale = ((double) MainMenuActivity.resolutionScale / 100.0); SCREEN_WIDTH = (int) (ACTUAL_SCREEN_WIDTH * scale); SCREEN_HEIGHT = (int) (ACTUAL_SCREEN_HEIGHT * scale); DENSITY = ACTUAL_DENSITY * scale; // Setup graphics requestWindowFeature(Window.FEATURE_NO_TITLE); surface_view = new GLSurfaceView(this); if (SCREEN_WIDTH != ACTUAL_SCREEN_WIDTH || SCREEN_HEIGHT != ACTUAL_SCREEN_HEIGHT) surface_view.getSurfaceHolder().setFixedSize(SCREEN_WIDTH, SCREEN_HEIGHT); 

Estoy recargando todo correctamente en GLSurfaceView (es decir, golpear a casa y volver al juego recarga las texturas, etc).

He imprimido la orientación en onWindowFocusChanged, y es el paisaje (como se esperaba).

El problema no aparece si no utilizo setFixedSize (es decir, si resolutionScale es 100). Además, el problema desaparece si aparece otra ventana delante del juego (como la ventana de preferencias) y luego devuelve el juego.

Gracias por adelantado. He estado probando cosas aleatorias durante una hora, ya que la investigación se secó.

  • Para Android, ¿dónde puedo encontrar una lista completa de @SuppressLint identificadores de problemas válidos
  • Error: (31, 0) Gradle Método DSL no encontrado: 'jniDebugBuild ()'
  • Cambiar el color de texto de NumberPicker
  • Cambiar el directorio de compilación gradle en android studio?
  • Cómo obtener el nombre de archivo de la ruta del archivo en android
  • ¿Cómo no ofuscar los métodos de interfaz y sus parámetros usando Progaurd en android?
  • Aplicar filtros personalizados a la salida de la cámara
  • Tipo de entrada adecuado para tarjetas de crédito
  • 4 Solutions collect form web for “Android OpenGL: relación de aspecto loco después de dormir”

    Estoy trabajando en este tema ahora, y en este momento parece ser un error de Android relacionado con SurfaceHolder.setFixedSize ().

    Lo que hago para obtener estos registros es esto: esperar a que el juego para cargar, empujar la energía, dejar la pantalla en blanco, empujar la energía de nuevo (rápidamente), desbloquear la diapositiva (rápidamente). Esto está en HTC Thunderbolt 2.3.4, por cierto.

    Aquí está el curso normal de los eventos (sin usar setFixedSize):

     ----- power button pushed ------ JavaMain: onPause: called, thread: 1 ActivityManager: Config changed: { scale=1.0 imsi=310/12 loc=en_US touch=3 keys=1/1/2 nav=1/1 orien=1 layout=34 uiMode=17 seq=1509 skin=default} JavaMain: onConfigurationChanged, orientation: 1 thread: 1 JavaMain: mSView(old): 800x480 JavaMain: surfaceChanged: width: 480, height:800, thread: 1 JavaMain: onWindowFocusChanged: called, thread: 1 (screen is now off) ------ power button pushed, and slide-lock undone ----- JavaMain: onResume: called, thread: 1 ActivityManager: Config changed: { scale=1.0 imsi=310/12 loc=en_US touch=3 keys=1/1/2 nav=1/1 orien=2 layout=34 uiMode=17 seq=1510 skin=default} JavaMain: onConfigurationChanged, orientation: 2 thread: 1 JavaMain: mSView(old): 480x800 JavaMain: onWindowFocusChanged: called, thread: 1 JavaMain: surfaceChanged: width: 800, height:480, thread: 1 (back in game) 

    Tenga en cuenta, que después de onPause, mi vista de la superficie se vuelve a hacer como retrato y después onResume se cambia de nuevo a paisaje. Tengo screenOrientation fijado al paisaje en el manifiesto.

    Ahora mira lo que ocurre durante la misma secuencia, pero ahora SurfaceHolder.setFixedSize () se utiliza (para reducir la resolución):

     ----- power button pushed ------- JavaMain: onPause: called, thread: 1 ActivityManager: Config changed: { scale=1.0 imsi=310/12 loc=en_US touch=3 keys=1/1/2 nav=1/1 orien=1 layout=34 uiMode=17 seq=1513 skin=default} JavaMain: onConfigurationChanged, orientation: 1 thread: 1 JavaMain: mSView(old): 800x480 JavaMain: surfaceChanged: width: 640, height:384, thread: 1 JavaMain: onWindowFocusChanged: called, thread: 1 (screen is now off) ------ power button pushed, and slide-lock undone ----- JavaMain: onResume: called, thread: 1 ActivityManager: Config changed: { scale=1.0 imsi=310/12 loc=en_US touch=3 keys=1/1/2 nav=1/1 orien=2 layout=34 uiMode=17 seq=1514 skin=default} JavaMain: onConfigurationChanged, orientation: 2 thread: 1 JavaMain: mSView(old): 480x800 JavaMain: onWindowFocusChanged: called, thread: 1 (back in game, with a messed up screen as in OP) 

    Ahora note que, después de onPause, surfaceChanged refleja el tamaño fijo que había especificado, sin embargo, en onResume la vista de la superficie está en orientación vertical (algo inesperado). Pero lo que realmente falta, es la llamada surfaceChanged con mis parámetros de tamaño fijo. Y antes de pedir, no hacer .setFixedSize () en onConfigurationChanged () no tiene ningún efecto.

    ACTUALIZACIÓN Y SOLUCIÓN:

    De hecho, la solución se redujo a restaurar (en realidad, nunca permitiendo cambios) a mi vista de la superficie. Esto se logra agregando las siguientes dos líneas después de la super llamada en onConfigurationChanged para su actividad. (Asumiendo que tiene el siguiente conjunto de ajustes de manifiesto).

     android:configChanges="orientation" android:screenOrientation="landscape" 

    Esto impide efectivamente que las dimensiones de la vista de la superficie se fijen nunca a otra cosa (como el retrato). Que, por cierto, ES LO QUE QUERÍA CUANDO ESPECIFIQUE screenOrientation = paisaje !!! (Te estoy mirando aquí, Google)

     public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // -- stomp any attempts by the OS to resize my view. // -- Hardcoded values for illustration only. In real life // -- you'll need to save these when the surface view is originally created mSView.getLayoutParams().width = 800; mSView.getLayoutParams().height = 480; } 

    Necesitas llamar a gl.glViewport (0, 0, width, height); O similar del método onSurfaceChanged de su GL10.Renderer. Mi suposición es que cuando el dispositivo se despierta del sueño, algo debe estar alterando el viewport, sin embargo el viewport se inicializa para usted cuando su aplicación se lanza por primera vez, por lo que funciona correctamente hasta que duerma.

    Estado de OpenGL y actividades de pausa / reanudación

    También debe tener en cuenta que su contexto de OpenGL (todos sus estados actuales como el color actual, las texturas enlazadas, etc.) se perderán cuando su actividad se detenga / reanude .
    Así que tal vez usted se enfrenta a un problema de pérdida de contexto.
    Si está utilizando una clase GLSurfaceView.Renderer debe volver a establecer sus estados de nuevo en el método onSurfaceCreated (..). Debería actualizar su pregunta con algún código.

    Actualizado Sólo por referencia que se refiere el comentario en: http://www.youtube.com/watch?v=cdvaPyq_eBU (38:14 min) y el uso de setFixedSize (..)

    http://developer.android.com/reference/android/view/SurfaceHolder.html#setFixedSize%28int,%20int%29
    Indica que debe llamar al método setFixedSize (SCREEN_WIDTH, SCREEN_HEIGHT) del mismo subproceso que ejecuta la ventana de SurfaceView. Parece que se está configurando desde su hilo ui y no el hilo de renderizado .

    Necesita hacer tres pasos:

    1. AndroidManifest.xml – android:configChanges="keyboard|keyboardHidden|screenSize|orientation"
    2. Su diseño para el uso de la actividad FrameLayout
    3. En código java

      Public void onSurfaceChanged (GL10 gl, int w, int h) {// necesitas test w> h y solo entonces haz tu inicialización de gráficos …}

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.