Meine Werkzeuge
Namensräume
Varianten

OpenGL ES Jumpstart

Aus indiedev
Version vom 19. November 2014, 10:25 Uhr von Glatzemann (Diskussion | Beiträge)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche
OpenGL ES Jumpstart
Projektanlage und erste Schritte
Autor Roland "Glatzemann" Rosenkranz
Programmier­sprache Java
Kategorie Android
Diskussion Thread im Forum
Lizenz indiedev article license


Inhaltsverzeichnis

Vorwort

Nachdem nun einige Jahre nach der Erfindung der neuen Geräteklasse "Smartphone" vergangen sind, haben sich drei mehr oder weniger große Systeme (iOS, Android, Windows Phone) und eine Menge Varianten (Firefox OS, Firephone, Cyanogen, etc.) herauskristallisiert.

In diesem Jumpstart möchte ich mehrere Tutorials anbieten, die sich auf die Entwicklung von Spielen mit OpenGL ES unter Android beziehen. Ich werde dabei mit den absoluten Grundlagen anfangen und nach und nach alle wichtigen Informationen zum grafischen Teil der Spieleentwicklung vermitteln.

In diesem ersten Tutorial möchte ich euch zeigen, wie man OpenGL ES unter Android im Vollbild-Modus initialisiert und den Bildschirm mit einer Farbe einfärbt (löscht). Dieses Tutorial wird die Basis für weitere Tutorials sein, in denen ich euch zeigen werde, wie man primitive Geometrien (Dreiecke, Rechtecke etc.) rendert und wie diese texturiert werden können. Damit habt ihr dann die Basis für den grafischen Teil eigener Spiele.

Ich gehe an dieser Stelle davon aus, daß ihr bereits das Android SDK geladen, installiert und eingerichtet habe. Sollte dies nicht der Fall sein, möchte ich an dieser Stelle auf mein Tutorial Android SDK einrichten verweisen. Dort wird alles wichtige erklärt und ein schneller Einstieg ermöglicht.

Das Inhaltsverzeichnis

Ich werde in diesem Artikel eine Art Inhaltsverzeichnis pflegen, die auf die Folgeartikel verweisen wird. Dieses Inhaltsverzeichnis ermöglicht die schnelle und einfache Navigation zwischen den Artikeln und man kann leicht einzelne Themengebiete wiederfinden und auch Dinge, die man bereits beherrscht überspringen.

Projekt anlegen

Zunächst müssen wir ein Projekt erzeugen, mit dem wir arbeiten können. Dazu starten wir die Eclipse Android IDE. Danach wählt ihr den Menüpunkt File/New Android Project. Daraufhin erscheint die folgende Maske, die ihr einfach wie im Screenshot dargestellt mit Werten befüllt. Die meisten Einstellungen belassen wir aber auf dem Standard.

01OpenGLESProjektEinrichten.JPG

Alle weiteren Schritte des Wizards lassen wir so, wie sie sind. Mit einer einzigen Ausnahme: Auf der Seite "Create Activity" deaktivieren wir die Option "Create Activity", da wird dies gleich per Hand vornehmen werden.

Das Grundgerüst von unserem Tutorial-Beispiel wurde nun von der Eclipse IDE für uns eingerichtet. Wir müssen nun lediglich dem Projekt mitteilen, daß wir OpenGL ES verwenden möchten. Wir verwenden erstmal die Version 2.0, da dies auf vielen Geräten läuft und das Feature Set der neueren Versionen erstmal nicht benötigt wird. Wir öffnen dazu die Datei AndroidManifest.xml durch einen Doppelklick. Es öffnet sich eine XML-Datei und wir fügen die folgende Zeile innerhalb des manifest-Tags ein:


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

Der Container

Um eine Grafik mit OpenGL ES darzustellen benötigen wir einen View Container. Glücklicherweise nimmt uns das Android SDK einen Teil der Arbeit ab und stellt uns GLSurfaceView und GLSurfaceView.Renderer zur Verfügung. Ersteres ist eben dieser View Container, in dem OpenGL Grafik darstellen kann und zweiteres steuert, was in diesem View angezeigt werden soll. Detail-Informationen zu diesen beiden Klassen findet ihr im OpenGL ES Developer Guide.

Ich möchte euch an dieser Stelle nicht verschweigen, daß GLSurfaceView nur eine Möglichkeit ist, Grafik auf den Bildschirm zu zaubern. Es ist eine gute und einfache Möglichkeit für Spiele, die im Vollbild-Modus (oder Fast-Vollbild) laufen sollen. Wenn ihr nur Teile einer App mit OpenGL ES rendern möchtet, dann solltet ihr besser den TextureView verwenden. Und wenn ihr alles selbst machen möchtet und euch nicht auf GLSurfaceView verlassen wollt, dann steht euch natürlich noch dessen Basisklasse SurfaceView zur Verfügung. Dabei müsst ihr jedoch eine erhebliche eigene Menge an Code beisteuern um ein ähnliches Ergebnis zu erhalten.

Renderer Klasse

Wir fangen einfach "unten" an, damit wir nicht so viele Compiler-Fehler erhalten. Als erstes kommt der Renderer. Wir erzeugen einfach ein neues Paket im src Ordner des Projekt. Dazu klicken wir den Ordner mit der rechten Maustaste an, wählen New/Package und vergeben den Namen de.indiedev.opengles_tutorial_01. Wichtig ist, daß dieser Paketname mit dem übereinstimmt, den wir bei Anlage des Projektes festgelegt haben. Wenn diese sich nicht decken, dann werden im weiteren Verlauf des Tutorials bestimmte Dinge nicht gefunden und es kommt zu Laufzeitfehlern. Danach klicken wir das gerade erzeugt Paket mit der rechten Maustaste an und wählen New/File und vergeben den Namen SimpleRenderer.java. Den eigentlichen Dateitypen müssen wir nicht auswählen, da Eclipse diesen automatisch anhand der Endung erkennt. Daher ist es auch wichtig, daß wir das Suffix .java anhängen, den sonst wäre dies nicht möglich. Die Klasse wird nun automatisch im ausgwählten Package geführt.

Die Klasse selbst ist sehr simpel. Diese implementiert einfach die Schnittstelle GLSurfaceView.Renderer, wodurch drei Methoden vorgegeben werden. Die einfachste Variante der Klasse sieht wie folgt aus:


package de.indiedev.opengles_tutorial_01;

import javax.microedition.khronos.opengles.GL10;

import javax.microedition.khronos.egl.EGLConfig;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;

public class SimpleRenderer implements GLSurfaceView.Renderer
{
	   public void onSurfaceCreated(GL10 unused, EGLConfig config) {
	        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	    }

	    public void onDrawFrame(GL10 unused) {
	        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
	    }

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

}

Die erste Methode die wir implementieren müssen nennt sich onSurfaceCreated. Diese Methode wird ein einziges mal aufgerufen und zwar dann, wenn das Spiel startet und das Surface erstmalig erzeugt wird.

Die zweite Methode heisst onDrawFrame und wird immer dann aufgerufen, wenn ein Frame gerendert werden muss. Je nach Einstellung ist dies z.B. 30x pro Sekunde, es kann aber auch nur dann geschehen, wenn sich etwas geändert hat (was Rechenleistung und Strom bzw. Akku spart).

Die letzte Methode trägt den Namen onSurfaceChanged. Diese Methode wird immer dann aufgerufen, wenn sich die Bildschirmauflösung oder -orientierung ändert.

Auf den Inhalt der Methoden möchte ich jetzt nicht im Detail eingehen, da dies erstmal noch nicht so wichtig ist um das Beispiel zu verstehen. Trotzdem möchte ich ein paar Worte darüber verlieren. In onSurfaceCreated wird die Hintergrundfarbe unseres Spiels festgelegt. Dies geschieht mit dem Befehl GLES20.glClearColor und muss nur einmalig vorgenommen werden. In onDrawFrame wird dann der Bildschirminhalt gelöscht. Dazu wird die Farbe verwendet, die wir zuvor in onSurfaceCreated festgelegt haben. Wenn sich die Ausrichtung des Gerätes oder die Auflösung ändert, dann müssen wir das OpenGL mitteilen. Dies passiert in der Methode onSurfaceChanged. Wir übergeben einfach die neue Größe als Vollbild-Viewport mit dem Befehl GLES20.glViewport.

Das war auch schon der Renderer.

View Klasse

Die View Klasse zu erzeugen ist noch deutlich einfacher als die Renderer-Klasse. Wie schon erwähnt, nimmt uns die Basisklasse GLSurfaceView die harte Arbeit ab und wir müssen lediglich festlegen, welcher Renderer verwendet werden soll. Wir erzeugen also wieder eine Klasse, diesmal mit dem Namen View und verwenden den folgenden Code.


package de.indiedev.opengles_tutorial_01;

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

public class View extends GLSurfaceView
{

	public View(Context context) {
		super(context);
		setRenderer(new SimpleRenderer());
	}
	
}

Dabei ist eigentlich nur die Zeile mit setRenderer interessant, da wir dort unseren SimpleRenderer aus dem vorherigen Abschnitt als aktiven Renderer festlegen.

Und das war auch schon der View.

Die Activity

Die letzte Klasse, die wir in diesem Tutorial anlegen müssen ist eine Activity. In der Activity wird festgelegt, was passieren soll, wenn unser Spiel startet. Auch hier benötigen wir nur sehr wenig Code, denn wir erzeugen lediglich unseren zuvor entwickelten View und setzen diesen als aktiv.

Wie mittlerweile bereits gewohnt erzeugen wir eine neue Quellcode-Datei und geben dieser den Namen GLESActivity.java.

Der Code ist einfach, übersichtlich und sollte selbsterklärend sein.


package de.indiedev.opengles_tutorial_01;

import android.app.Activity;
import android.os.Bundle;

public class GLESActivity extends Activity {

    private View view;

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

        view = new View(this);
        setContentView(view);
    }
}

Ein wichtiger Punkt fehlt nun noch, bevor wir unser erstes "Spiel" bewundern können. Wir müssen die Activity registrieren. Dazu öffnen wir erneut die Datei AndroidManifest.xml durch einen Doppelklick und fügen den folgenden, neuen Tag inherlab des Application-Tag ein.


       <activity
            android:name=".GLESActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

Starten

Wir haben nun den gesamten Code unseres ersten Android-Spiels (was natürlich noch ziemlich übertrieben ist) erzeugt. Wir sollten sicherstellen, daß alles gespeichert ist (Die "Save All" Funktion aus der Toolbar ist dabei sehr hilfreich). Wir wählen jetzt einfach unser Projekt als aktives durch einen Links-Klick im Package Explorer von Eclipse aus. Dann klicken wir das Debug-Symbol aus der Toolbar. Natürlich sollte ein Android-Smartphone per USB angeschlossen sein, oder ein entsprechender Emulator eingerichtet sein. Es wird nun ein APK-Paket erzeugt, auf dem Geräte oder Emulator installiert und gestartet.

Wir sehen jetzt einen schwarzen Bildschirm.

Wenn wir Breakpoints im Renderer setzen, können wir das Verhalten untersuchen und sicherstellen, daß dieses so funktioniert, wie ich es weiter oben beschrieben habe.

Zusammenfassung und Ausblick

In diesem kurzen Tutorial habe ich erklärt, wie man ein einfaches OpenGL ES-Projekt für Android erzeugt und eine einfache Clear-Methode von OpenGL aufruft um den Hintergrund schwarz einzufärben. Damit haben wir die Grundlagen für weiterführende OpenGL Themen erarbeitet und die Basis für die Spieleentwicklung unter Android geschaffen.

Im nächsten Teil möchte ich euch zeigen, wie man mit OpenGL Dreiecke rendert und so eine Einführung in einfache, grafische Primitive geben. In weiteren Teilen werden wir uns dann mit Shadern, Texturen und Sprites beschäftigen und alles erarbeiten, was wir für ein Spiel benötigen.

Aufgaben für den Leser

In diesem Bereich möchte ich den Leser dazu ermutigen, sich ein wenig mit dem hier vermittelten Wissen zu beschäftigen und dieses selbständig auszubauen. Diese Aufgaben sind optional, aber sehr gut dazu geeignet das Erlernte zu festigen. Probleme diesbezüglich können mit der Diskussionsfunktion natürlich gerne besprochen werden.

  • Verändere die Hintergrundfarbe des Bildschirms (z.B. rot)
  • Verändere die Hintergrundfarbe des Bildschirms je nach Ausrichtung des Gerät
Navigation
Tutorials und Artikel
Community Project
Werkzeuge