OpenGL ES-Umgebung erstellen

Zum Zeichnen von Grafiken mit OpenGL ES in Ihrer Android-App müssen Sie einen Ansichtscontainer dafür erstellen. Die einfachere Möglichkeit, dies zu tun, ist die Implementierung von GLSurfaceView und GLSurfaceView.Renderer. Ein GLSurfaceView ist ein Ansichtscontainer für Grafiken, die mit OpenGL gezeichnet wurden, und GLSurfaceView.Renderer steuert, was in dieser Ansicht gezeichnet wird. Weitere Informationen zu diesen Klassen finden Sie im OpenGL ES-Entwicklerhandbuch.

GLSurfaceView ist nur eine Möglichkeit, OpenGL ES-Grafiken in Ihre Anwendung zu integrieren. Für eine Grafikansicht im Vollbild- oder bildschirmfüllenden Bildschirm ist dies eine vernünftige Wahl. Entwickler, die OpenGL ES-Grafiken in einen kleinen Teil ihrer Layouts einbinden möchten, sollten sich TextureView ansehen. Für echte Do-it-yourself-Entwickler ist es auch möglich, mit SurfaceView eine OpenGL ES-Ansicht zu erstellen. Dafür muss aber viel zusätzlicher Code geschrieben werden.

In dieser Lektion wird erläutert, wie Sie eine minimale Implementierung von GLSurfaceView und GLSurfaceView.Renderer in einer einfachen Anwendungsaktivität vornehmen.

Verwendung von OpenGL ES im Manifest deklarieren

Damit Ihre Anwendung die OpenGL ES 2.0 API verwenden kann, müssen Sie Ihrem Manifest die folgende Deklaration hinzufügen:

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

Wenn deine Anwendung die Texturkomprimierung verwendet, musst du auch angeben, welche Komprimierungsformate von der Anwendung unterstützt werden, damit sie nur auf kompatiblen Geräten installiert wird.

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

Weitere Informationen zu Texturkomprimierungsformaten finden Sie im OpenGL-Entwicklerleitfaden.

Aktivität für OpenGL ES-Grafiken erstellen

Android-Anwendungen, die OpenGL ES verwenden, verfügen über Aktivitäten wie jede andere Anwendung mit einer Benutzeroberfläche. Der Hauptunterschied zu anderen Anwendungen besteht darin, was du in das Layout für deine Aktivität eingibst. In vielen Anwendungen kannst du TextView, Button und ListView verwenden. Bei Apps mit OpenGL ES kannst du aber auch GLSurfaceView hinzufügen.

Das folgende Codebeispiel zeigt eine minimale Implementierung einer Aktivität, die GLSurfaceView als primäre Ansicht verwendet:

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);
    }
}

Hinweis:Für OpenGL ES 2.0 ist Android 2.2 (API-Level 8) oder höher erforderlich. Dein Android-Projekt muss also auf diese API oder höher ausgerichtet sein.

GLSurfaceView-Objekt erstellen

Ein GLSurfaceView ist eine spezielle Ansicht, in der OpenGL ES-Grafiken gezeichnet werden. Sie allein erreichen nicht viel. Das Zeichnen der Objekte wird in der GLSurfaceView.Renderer gesteuert, die Sie in dieser Ansicht festlegen. Tatsächlich ist der Code für dieses Objekt so dünn, dass Sie versucht sein könnten, die Erweiterung zu überspringen und einfach eine unveränderte GLSurfaceView-Instanz zu erstellen. Tun Sie das aber nicht. Sie müssen diese Klasse erweitern, um Berührungsereignisse zu erfassen. Dies wird in der Lektion Auf Berührungsereignisse antworten behandelt.

Der wesentliche Code für GLSurfaceView ist minimal. Für eine schnelle Implementierung ist es daher üblich, einfach eine innere Klasse in der Aktivität zu erstellen, in der der Code verwendet wird:

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);
    }
}

Eine weitere optionale Ergänzung zur GLSurfaceView-Implementierung besteht darin, den Renderingmodus so einzustellen, dass die Ansicht nur dann gezeichnet wird, wenn sich die Zeichendaten mithilfe der Einstellung GLSurfaceView.RENDERMODE_WHEN_DIRTY ändern:

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);

Mit dieser Einstellung wird verhindert, dass der Frame GLSurfaceView neu gezeichnet wird, bis Sie requestRender() aufrufen, was für diese Beispielanwendung effizienter ist.

Renderer-Klasse erstellen

Bei der Implementierung der GLSurfaceView.Renderer-Klasse oder des Renderers in einer Anwendung, die OpenGL ES verwendet, wird es interessant. Diese Klasse steuert, was auf der GLSurfaceView dargestellt wird, mit der sie verknüpft ist. Es gibt drei Methoden in einem Renderer, die vom Android-System aufgerufen werden, um herauszufinden, was und wie auf einem GLSurfaceView gezeichnet wird:

  • onSurfaceCreated(): Wird einmal aufgerufen, um die OpenGL ES-Umgebung der Ansicht einzurichten.
  • onDrawFrame() – Wird bei jeder Neuzeichnung der Ansicht aufgerufen.
  • onSurfaceChanged() – Wird aufgerufen, wenn sich die Geometrie der Ansicht ändert, z. B. wenn sich die Bildschirmausrichtung des Geräts ändert.

Hier ist eine sehr einfache Implementierung eines OpenGL ES-Renderers, der lediglich einen schwarzen Hintergrund im GLSurfaceView zeichnet:

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);
    }
}

Das ist alles! Die obigen Codebeispiele erstellen eine einfache Android-Anwendung, die mithilfe von OpenGL einen schwarzen Bildschirm anzeigt. Dieser Code bewirkt nichts, was sehr interessant ist. Durch das Erstellen dieser Klassen haben Sie jedoch den Grundstein gelegt, um grafische Elemente mit OpenGL zu zeichnen.

Hinweis: Sie fragen sich vielleicht, warum diese Methoden einen GL10-Parameter haben, wenn Sie die OpengGL ES 2.0 APIs verwenden. Diese Methodensignaturen werden einfach für die APIs 2.0 wiederverwendet, um den Android-Framework-Code zu vereinfachen.

Wenn Sie mit den OpenGL ES APIs vertraut sind, sollten Sie jetzt in der Lage sein, eine OpenGL ES-Umgebung in Ihrer App einzurichten und Grafiken zu zeichnen. Solltest du weitere Hilfe bei den ersten Schritten mit OpenGL benötigen, kannst du in den nächsten Lektionen weiterlesen.