Cómo construir un entorno de OpenGL ES

A fin de dibujar gráficos con OpenGL ES en tu aplicación para Android, debes crear un contenedor de vistas para ellos. Una de las formas más sencillas de hacerlo es implementar un GLSurfaceView y un GLSurfaceView.Renderer. Un GLSurfaceView es un contenedor de vista para gráficos dibujados con OpenGL y GLSurfaceView.Renderer controla lo que se dibuja dentro de esa vista. Para obtener más información sobre estas clases, consulta la guía para desarrolladores de OpenGL ES.

GLSurfaceView es solo una forma de incorporar gráficos de OpenGL ES en tu aplicación. Para una vista de gráficos de pantalla completa o casi completa, es una opción razonable. Los desarrolladores que quieran incorporar gráficos de OpenGL ES en una pequeña parte de sus diseños deben consultar TextureView. Los desarrolladores que hacen todo por su cuenta también pueden crear una vista de OpenGL ES con SurfaceView, pero esto requiere escribir un poco de código adicional.

En esta lección, se explica cómo completar una implementación mínima de GLSurfaceView y GLSurfaceView.Renderer en una actividad de aplicación simple.

Cómo declarar el uso de OpenGL ES en el manifiesto

Para que tu aplicación use la API de OpenGL ES 2.0, debes agregar la siguiente declaración en el manifiesto:

<uses-feature android:glEsVersion="0x00020000" android:required="true" />

Si tu aplicación usa compresión de texturas, también debes declarar qué formatos de compresión admite para que solo se instale en dispositivos compatibles.

<supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" />
<supports-gl-texture android:name="GL_OES_compressed_paletted_texture" />

Para obtener más información sobre los formatos de compresión de texturas, consulta la guía para desarrolladores de OpenGL.

Crea una actividad para los gráficos de OpenGL ES

Las aplicaciones para Android que usan OpenGL ES tienen actividades como cualquier otra aplicación que tenga una interfaz de usuario. La principal diferencia con otras aplicaciones es lo que pones en el diseño de tu actividad. Si bien en muchas aplicaciones puedes usar TextView, Button y ListView, en una app que usa OpenGL ES, también puedes agregar GLSurfaceView.

En el siguiente ejemplo de código, se muestra una implementación mínima de una actividad que utiliza un GLSurfaceView como vista principal:

Kotlin

class OpenGLES20Activity : Activity() {

    private lateinit var gLView: GLSurfaceView

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Create a GLSurfaceView instance and set it
        // as the ContentView for this Activity.
        gLView = MyGLSurfaceView(this)
        setContentView(gLView)
    }
}

Java

public class OpenGLES20Activity extends Activity {

    private GLSurfaceView gLView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Create a GLSurfaceView instance and set it
        // as the ContentView for this Activity.
        gLView = new MyGLSurfaceView(this);
        setContentView(gLView);
    }
}

Nota: OpenGL ES 2.0 requiere Android 2.2 (nivel de API 8) o una versión posterior, así que asegúrate de que tu proyecto de Android se oriente a esa API o a versiones posteriores.

Cómo construir un objeto GLSurfaceView

Un GLSurfaceView es una vista especializada en la que puedes dibujar gráficos de OpenGL ES. No hace mucho por sí sola. El dibujo real de los objetos se controla en el GLSurfaceView.Renderer que configuraste en la vista. De hecho, el código para este objeto es tan delgado que puede que te veas tentado a no extenderlo y simplemente crear una instancia de GLSurfaceView sin modificar, pero no lo hagas. Debes extender esta clase para capturar eventos táctiles. Ese tema se aborda en la lección Responde a eventos táctiles.

El código esencial de una GLSurfaceView es mínimo. Por lo tanto, para una implementación rápida, es común crear una clase interna en la actividad que la usa:

Kotlin

import android.content.Context
import android.opengl.GLSurfaceView

class MyGLSurfaceView(context: Context) : GLSurfaceView(context) {

    private val renderer: MyGLRenderer

    init {

        // Create an OpenGL ES 2.0 context
        setEGLContextClientVersion(2)

        renderer = MyGLRenderer()

        // Set the Renderer for drawing on the GLSurfaceView
        setRenderer(renderer)
    }
}

Java

import android.content.Context;
import android.opengl.GLSurfaceView;

class MyGLSurfaceView extends GLSurfaceView {

    private final MyGLRenderer renderer;

    public MyGLSurfaceView(Context context){
        super(context);

        // Create an OpenGL ES 2.0 context
        setEGLContextClientVersion(2);

        renderer = new MyGLRenderer();

        // Set the Renderer for drawing on the GLSurfaceView
        setRenderer(renderer);
    }
}

Otra adición opcional a tu implementación de GLSurfaceView es configurar el modo de renderización para que solo dibuje la vista cuando haya un cambio en los datos de dibujo mediante la configuración GLSurfaceView.RENDERMODE_WHEN_DIRTY:

Kotlin

// Render the view only when there is a change in the drawing data
renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY

Java

// Render the view only when there is a change in the drawing data
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

Esta configuración evita que el marco GLSurfaceView se vuelva a dibujar hasta que llames a requestRender(), que es más eficiente para la app de ejemplo.

Cómo compilar una clase de procesador

La implementación de la clase GLSurfaceView.Renderer, o procesador, dentro de una aplicación que usa OpenGL ES es donde todo comienza a ponerse interesante. que controla lo que se dibuja en el GLSurfaceView con el que está asociada. En un procesador, el sistema Android llama a tres métodos para determinar qué dibujar en una GLSurfaceView y cómo hacerlo:

  • onSurfaceCreated(): Se llama una vez para configurar el entorno de OpenGL ES de la vista.
  • onDrawFrame(): Se llama cada vez que se vuelve a dibujar la vista.
  • onSurfaceChanged(): Se llama cuando cambia la geometría de la vista, por ejemplo, cuando cambia la orientación de la pantalla del dispositivo.

A continuación, se incluye una implementación muy básica de un procesador de OpenGL ES que no hace más que dibujar un fondo negro en el GLSurfaceView:

Kotlin

import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10

import android.opengl.GLES20
import android.opengl.GLSurfaceView

class MyGLRenderer : GLSurfaceView.Renderer {

    override fun onSurfaceCreated(unused: GL10, config: EGLConfig) {
        // Set the background frame color
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f)
    }

    override fun onDrawFrame(unused: GL10) {
        // Redraw background color
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
    }

    override fun onSurfaceChanged(unused: GL10, width: Int, height: Int) {
        GLES20.glViewport(0, 0, width, height)
    }
}

Java

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;

public class MyGLRenderer implements GLSurfaceView.Renderer {

    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        // Set the background frame color
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    }

    public void onDrawFrame(GL10 unused) {
        // Redraw background color
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    }

    public void onSurfaceChanged(GL10 unused, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
    }
}

Eso es todo. Los ejemplos de código anteriores crean una aplicación para Android simple que muestra una pantalla negra con OpenGL. Si bien este código no hace nada muy interesante, cuando creas estas clases, sientas las bases que necesitas para comenzar a dibujar elementos gráficos con OpenGL.

Nota: Quizás te preguntes por qué estos métodos tienen un parámetro GL10 cuando usas las APIs de OpenGL ES 2.0. Estas firmas de método simplemente se reutilizan para las APIs 2.0 a fin de simplificar el código del framework de Android.

Si estás familiarizado con las APIs de OpenGL ES, ahora deberías poder configurar un entorno de OpenGL ES en tu app y comenzar a dibujar gráficos. Sin embargo, si necesitas un poco más de ayuda para comenzar a usar OpenGL, continúa en las siguientes lecciones para obtener más sugerencias.