Upload
lytram
View
220
Download
0
Embed Size (px)
Christian Klotz 07.01.2009
Betreuer: Prof. Dr. Werner Heinzel
HS Fulda – Fachbereich Angewandte Informatik
Analyse und
praktische Erprobung
von OpenGL ES auf
der Android Plattform Ausarbeitung im Rahmen der LVA Graphisch-Interaktive Systeme
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 2
Inhaltsverzeichnis
1 Abstract .......................................................................................................................................3
2 Einführung...................................................................................................................................3
3 Android........................................................................................................................................4
3.1 Warum wurde Android entwickelt?....................................................................................4
3.2 Endgeräte für die Android Plattform ..................................................................................5
3.3 Die Architektur von Android ...............................................................................................5
3.4 Aufbau einer Anwendung ...................................................................................................7
4 OpenGL ES in Android .................................................................................................................8
5 Die Entwicklungsumgebung ......................................................................................................11
6 Das Tutorial ...............................................................................................................................12
6.1 Tutorial 1 – Das Dreieck ....................................................................................................13
6.2 Infos zu Tutorials 2, 3 und 4 ..............................................................................................23
7 Erkenntnisse der Ausarbeitung .................................................................................................23
8 Schlusswort ...............................................................................................................................24
9 Quellen ......................................................................................................................................25
9.1 Literaturverzeichnis...........................................................................................................25
9.2 Internetquellen .................................................................................................................25
10 Anhang ......................................................................................................................................27
10.1 Hilfe zur Entwicklungsgebung ...........................................................................................27
10.1.1 Einrichten der Entwicklungsumgebung ................................................................. 27
10.1.2 Nutzen der Entwicklungsumgebung ...................................................................... 32
10.1.2.1 Erstellung eines Projektes / Import eines bestehenden Projektes ............... 32
10.1.2.2 Der typische Aufbau einer Android Anwendung........................................... 34
10.1.2.3 Starten einer Anwendung auf dem Emulator ............................................... 38
10.1.2.4 Bedienung des Emulators.............................................................................. 40
10.1.2.5 Werkzeuge zum Debuggen und Tools zum Steuern des Emulators.............. 40
10.2 Anwenderdokumentation.................................................................................................41
10.3 Darstellung des Aufwandes...............................................................................................43
10.4 Aufbau der CD zur Ausarbeitung.......................................................................................44
10.5 Source-Code zum Tutorial 1 ..............................................................................................45
10.5.1 Listing 1: Klasse TutorialBasis................................................................................. 45
10.5.2 Listing 2: Klasse EGLHelper .................................................................................... 48
10.5.3 Listing 3: Klasse T1Dreieck ..................................................................................... 51
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 3
1 Abstract
Diese Ausarbeitung beschäftigt sich mit der Realisierung von 3D – Grafiken mittels OpenGL ES auf
der Android – Plattform. Die Android – Plattform ist ein Software-Paket für mobile Endgeräte und
besteht aus einem Betriebssystem, Middleware und einigen Anwendungen. Die Entwicklung
wurde im Jahr 2007 von der Open-Handset-Alliance gestartet. In Kapitel 2 wird genauer erklärt,
warum die Android-Plattform entwickelt wurde und aus welchen Komponenten diese besteht.
Mit der Integration und Umsetzung von OpenGL ES in die Android-Plattform beschäftigt sich das
Kapitel 4. In einem ausführlichen Tutorial in Kapitel 5 und 6 soll praktisch gezeigt werden, wie sich
OpenGL ES Programme mit der Programmiersprache Java in Android erstellen lassen. Für
Einsteiger in die Android-Programmierung empfiehlt sich das Kapitel 10.1 im Anhang, wo
detailliert die Einrichtung und die Nutzung der Entwicklungsumgebung geschildert wird.
2 Einführung
Die Welt der mobilen Endgeräte steht zurzeit vor einem gewaltigen Umbruch. Bisher wurden die
Handys fast ausschließlich zum Telefonieren und zum Versenden von Kurznachrichten verwendet.
Doch dieses Nutzungsverhalten der Anwender änderte sich in den letzten 1-2 Jahren mit der
Einführung von modernen Endgeräten und der damit verbundenen Infrastruktur durch die
Netzanbieter drastisch. Die neuen Handys, auch Smartphones oder Handsets genannt, werden
jetzt zum Surfen im Internet, zum Senden und Empfangen von E-Mails und sogar als portable
Spielekonsolen genutzt. Um diese Services auf dem Handy zu realisieren, wird zum einen eine
performante Hardware benötigt, die mittlerweile die Leistungsfähigkeit von 3-4 Jahren alten PCs
überschreitet. Zum anderen wird ein Betriebssystem auf dem Endgerät benötigt, das die Basis für
die komplexen Anwendungen darstellt. Bisher wurden auf Smartphones hauptsächlich die
Betriebssysteme Symbian OS, Windows ME, und Iphone OS eingesetzt. [EMBEDDEDOS] Um den
Nachteilen der bisherigen Betriebssysteme, wie z.B. hohe Lizenzkosten aus dem Weg zu gehen
wurde im November 2007 die „Open-Handset-Alliance“ (OHA) gegründet. Sie bildet einen
Zusammenschluss von mehr als 30 namhaften Firmen, darunter Handyhersteller wie Samsung,
Motorola, LG und HTC, Chiphersteller wie Intel und Texas Instruments,
Telekommunikationsunternehmen wie China Mobile und T-Mobile und die Softwareentwickler
Ebay und Google. [OHAMEMBERS] Ihr erklärtes Ziel ist, die Entwicklung eines gemeinsamen,
offenen und freien Software-Standards. Dieser Handset-Standard, genannt "Android", soll durch
geringere Entwicklungskosten günstigere Endgeräte ermöglichen, einen verbesserten
Funktionsumfang sowie leichtere Bedienbarkeit, bei gleichzeitig höherer Individualisierung des
Gerätes bieten.
Mit Andriod soll es möglich sein „innovative und bahnbrechende Anwendungen“ [ANDROIDDOC]
zu entwickeln. Dies sind unter anderem Anwendungen, die aufwendige 3D-Grafiken auf dem
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 4
Bildschirm des Geräts realisieren. Mögliche Szenarien sind z.B. die Verwendung in Spielen oder in
Navigationssoftware.
In dieser Ausarbeitung soll daher untersucht werden, wie sich 3D-Grafiken auf der Android-
Plattform realisieren lassen.
3 Android
3.1 Warum wurde Android entwickelt?
Die „Open-Handset-Alliance“ wurde Ende 2007 durch den Softwaregigant Google initiiert. Hier
tritt die Frage auf: Warum entwickelt ausgerechnet Google ein Open-Source-Software-Standard
für Handsets? Wie allgemein bekannt, ist Google der zurzeit führende Anbieter von Internet-
Dienstleitungen. Diesen Rang hat Google vor allem durch seine Marktführerschaft im Bereich der
Internetsuche und der damit verbundenen Vermarktung von Werbeanzeigen im Internet
erworben. Diese Marktführerschaft möchte Google mit Android noch weiter ausbauen, da jetzt
die Google Dienste, wie Online-Suche, Google-Mail oder Google-Maps auch auf mobilen
Endgeräten verwendet werden können. Das beeindruckende ist, die Größe des Marktes der
mobilen Endgeräte. Im Jahr 2007 wurden weltweit ca. 3,3 Milliarden Handys genutzt
[NUTZUNGMOB] und im Vergleich dazu „nur“ rund 1 Milliarde PCs [NUTZUNGPC]. Zwar gab es
schon bisher Smartphones mit denen das Surfen im Internet möglich war, aber bei keinem waren
die Google Dienstleistungen so konsequent integriert.
Doch auch die weiteren Mitglieder der OHA, die aus allen Bereichen der IT & TK-Industrie [siehe
Abbildung 1] stammen, sehen in Android eine Reihe von Vorteilen, welche durch den Open-
Source Ansatz entstehen [OHAFAQ] und beteiligen sich daher an der Allianz mit Google.
Nutznießer des offenen Ansatzes ist natürlich letztendlich auch der Endkunde. Er wird in der
Zukunft von niedrigeren Gerätepreisen, einer ausgereiften, von vielen Unternehmen gepflegten
Plattform und einem reichhaltigen, innovativen Softwareangebot profitieren. [PLEUMANN08]
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 5
Netzbetreiber Chip-Hersteller Telefonhersteller Software-Hersteller
• China Mobile
• KDDI
• NTT DoCoMo
• Sprint Nextel
• Softbank
• T-Mobile
• Telecom Italia
• Telefónica
• Vodafone
• Audience
• ARM Limited
• Broadcom
Corporation
• Intel Corporation
• Marvell Technology
Group
• NVIDIA Corporation
• Qualcomm • SiRF Technology
Holdings
• Synaptics
• Texas Instruments
• ASUSTeK
• HTC
• LG
• Motorola
• Samsung
Electronics
• Sony Ericsson
• Ascender Corporation
• eBay
• Esmertec
• LivingImage
• NMS Communications
• Nuance
Communications
• PacketVideo • SkyPop
• SONiVOX
• Aplix
• Noser Engineering
• The Astonishing Tribe
• Wind River Systems
Abbildung 1 Mitglieder der OHA [OHAMEMBERS2]
3.2 Endgeräte für die Android Plattform
Trotz der Entwicklungszeit von nur einem Jahr erschien im Oktober 2008 das erste Handset mit
Android, das „T-Mobile G1“ (siehe Abbildung Titelseite links) auf dem amerikanischen Markt. Das
vom Hersteller HTC entwickelte Gerät steht seinen Konkurrenten, wie z.B. dem Apple IPhone , in
Sachen Funktionalität um nichts nach. Die Einführung des „T-Mobile G1“ in Deutschland ist für
Anfang März 2009 geplant. [TMOBILEG1] Aber auch die anderen Hersteller der OHA wollen im
Jahr 2009 den Kunden Endgeräte anbieten.
3.3 Die Architektur von Android
In diesem Abschnitt soll die Architektur von Android vorgestellt werden, nur so ist es später
möglich den Aufbau einer selbstentwickelten Android-Anwendung zu verstehen. Die Android-
Plattform bildet einen kompletten Software-Stack, beginnend bei dem Betriebssystem über
Middleware bis zu den Anwendungen für den User ab. Der Aufbau dieses Stacks soll mit Hilfe der
Abbildung 2 veranschaulicht werden.
Die unterste Ebene der Plattform ist ein für mobile Endgeräte optimiertes Linux Betriebssystem.
Der Linux Kernel der Version 2.6 dient als Hardwareabstraktionsschicht, das bedeutet, dass die
höheren Schichten des Android Software-Stacks über das Linux auf die Hardware des Endgerätes
zugreifen. Damit das Linux-OS mit der Hardware des Endgerätes kommunizieren kann, müssen
Treiber eingesetzt werden. Für die Hersteller von mobilen Endgeräten ist es folglich recht einfach
Android einzusetzen, da sie „nur“ die entsprechenden Treiber einfügen oder anpassen müssen.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 6
Die nächste höhere Schicht der Architektur bilden die Bibliotheken. Sie sind in C oder C++
geschrieben und stellen die Verknüpfung zwischen Linux Kernel und Application Framework dar.
Des Weiteren sind sie verantwortlich für die hohe Performance des Android – Frameworks, da sie
nicht wie die höheren Schichten in Java geschrieben sind. Hier ist auch die Open Graphics Library
for Embedded Systems (OpenGL ES) angeordnet, die für die Realisierung von 3D-Grafiken benötigt
wird. Wenn ein entsprechender Chip in Geräte vorhanden ist, wird von der Bibliothek
hardwareunterstützte 3D-Grafikbeschleunigung angeboten. Hierzu jedoch mehr im Kapitel 4
OpenGL ES in Android“. Die Beschreibung der weiteren Bibliotheken würde den Umfang der
Arbeit sprengen, der interessierte Leser findet jedoch auf der Android Webseite [ANDROIDDOC]
ausführliche Informationen dazu.
Als nächstes folgt die Android Runtime. Der Hauptbestandteil der Runtime ist die Dalvik Virtual
Machine, eine von Google extra für mobile Endgeräte entwickelte Virtuelle Maschine (VM). Diese
ist für eingebettete Systeme mit begrenztem Speicher, Prozessorleistung und Akkulaufzeit
optimiert und ersetzt die klassische Java VM. Die Dalvik VM versteht einen geänderten Byte-Code,
der in .dex Dateien (Dalvik Executable) gespeichert wird. Um diese Dateien zu erhalten, wird der
Java-Byte-Code (.class Dateien) mit dem Werkzeug „dx“ in Dalvik-Bytecode konvertiert.
Außerdem werden in der Android Runtime die Kernbibliotheken von Java zu Verfügung gestellt.
Wie alle blau hinterlegten Boxen in Abbildung 2 sind auch die Core Libraries in Java geschrieben.
Das Application Framework ist das „Application Programming Interface“ (API) für Android und
stellt somit dem Programmierer eine Sammlung von Java Klassen zur Verfügung, die die
Programmierung von Anwendungen wesentlich erleichtern.
Die höchste Ebene der Architektur ist der Application Layer. Diese Anwendungsschicht beinhaltet
zum einen vorinstallierte Anwendungen, wie die Home-Anwendung (das Hauptmenü des
Handsets), den Browser oder die Telefonieanwendung, die jedes Smartphone benötigt.
Andererseits kann auch jeder Nutzer selbstgeschriebene oder von „Android Market“, dem Online-
Shop für Android Anwendungen, heruntergeladene Programme installieren.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 7
Abbildung 2 Architektur von Android. [ANDROIDDOC]
3.4 Aufbau einer Anwendung
Durch das Android Applikation Framework (AAF) wird festgelegt, dass jede Anwendung in
verschiedene Komponenten aufgeteilt wird. Diese Komponenten werden in Android als Bausteine
(building blocks) bezeichnet. Es gibt vier verschiedene Arten von Bausteinen [ANDROIDANA].
Activities
Diese Komponente stellt das User Interface dar, das der Handset-Nutzer von einer Applikation
sehen kann. Eine Anwendung besteht meist aus mehreren Aktivitäten. Beispielsweise würde eine
E-Mail Applikation aus zwei Activities bestehen. Eine zum Anzeigen des Posteingangs und eine
weitere zum Versenden einer Nachricht.
Services
Ein Service ist eine Komponente, die im Hintergrund abläuft und keine Interaktion mit Benutzer
hat. Dies ist vergleichbar mit einem Dienst in einem Windows oder Linux Betriebssystem.
Content-Provider
Mit dieser Komponente ist es möglich Daten über Applikationsgrenzen hinweg zu verteilen.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 8
Broadcast Intent Reciever
Der Baustein Broadcast Intent Reciever wird verwendet, wenn die Anwendung auf ein externes
Ereignis, wie zum Beispiel das Empfangen einer SMS oder ein eingehender Anruf reagieren soll.
Jede Anwendung besteht mindestens aus einem Applikationsbaustein.
Im Tutorial dieser Arbeit wird nur der Baustein Activity verwendet, daher soll dieser noch ein
bisschen genauer betrachtet werden.
Die Anwendungen für Android werden in der Programmiersprache Java entwickelt. Jede
selbstentwickelte Activity ist eine Java Klasse und erweitert die Basisklasse Activity , die durch
das AAF bereitgestellt wird. Die selbstentwickelte Klasse wird dann ein User Interface darstellen,
das aus Views besteht und auf Events durch den User reagiert. Eine View beschreibt, wie das
User Interface aussieht und wie es aufgebaut ist.
Soviel einführend rund um die Open-Source Plattform Android. Das nächste Kapitel beschäftigt
sich mit den Standard OpenGL ES und wie dieser in die Android Plattform integriert ist.
4 OpenGL ES in Android
Im Rahmen der Lehrveranstaltung „Graphisch-Interaktive Systeme“ an der Hochschule Fulda, die
der Ausarbeitung zu Grunde liegt, wurde das Thema OpenGL ES bereits ausführlich behandelt.
Daher soll im Rahmen dieser Arbeit OpenGL ES nur recht kurz vorgestellt und erklärt werden. Viel
mehr soll gezeigt werden, wie OpenGL ES auf dem eingebetteten System „Android“ eingesetzt
wird.
OpenGL ES ist ein kompakter und leistungsfähiger low-level 3D – Rendering Standard für
eingebettete Systeme. Dieser Standard basiert auf dem bekannten OpenGL Grafikstandard und
wurde von der Khronos Gruppe auf der Siggraph 2002 eingeführt. Der bisherige OpenGL Standard
wurde so verkleinert und angepasst, dass dieser schonender mit den eingeschränkten Ressourcen
auf eingebetteten Systemen umgeht. [MOBILE3E] [SIGGRAPH06]
In Android wird der OpenGL ES Standard in Version 1.0 vollständig implementiert, der auf dem
OpenGL Standart 1.3 basiert. Aber auch einige Funktionen des 1.1 Standards sind bereits
integriert. Es wird aber aktuell die Verwendung des 1.0 Standards empfohlen.
Es stellt sich aber unmittelbar die Frage, wie kann ich aus einer Java-Anwendung auf die in C
geschriebe OpenGL ES Bibliothek zugreifen? Zu diesem Zweck besitzt Android spezielle Java
Wrapperklassen, welche als Schnittstellen zu den nativen Funktionen dienen. Die Wrapperklassen
wurden nicht extra für Android entwickelt, sondern basieren auf dem „Java Binding for the
OpenGL ES“ (JOGLES), das im Java Specification Request 239 verabschiedet wurde. [JSR239]
Jedoch ist die API nicht völlig identisch, sondern wurde für die Android-Plattform leicht angepasst.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 9
Die genutzte Wrapperklasse GL10 befindet sich im Paket
javax.microedition.khronos.opengles und setzt die 106 nativen C Funktionen aus
der OpenGL ES 1.0 Spezifikation in 106 Java Methoden um. Die Methoden haben genau den
gleichen Namen wie die OpenGL ES Funktionen in C, nur die Parametertypen unterscheiden sich.
So wird aus der Funktion:
void glDrawElements(GLenum mode, GLsizei count, GLenum type, const
GLvoid * indices)
die Methode mit der Signatur:
public void glDrawElements( int mode, int count, int type, Buffer
i ndices)
Der geschulte Programmierer erkennt den Unterschied. Zum einen wird auf die Einführung von
neuen Datentypen verzichtet, stattdessen werden die Standardtypen wie „int“ und „float“
verwendet. Und zum anderen unterstützt Java bekanntlich keine Pointer, die auf Arrays zeigen.
Daher wird das neue Objekt „Buffer“ eingeführt, das ein Array aufnimmt und OpenGlLES zur
Verfügung stellt. Die Android Dokumentation im Java-Doc-Format für die Klasse GL10 ist unter
[GL10JAVADOC] zu finden. Leider ist dieser Teil der Java-Doc von Android nur unzureichend
dokumentiert. Daher ist gleichzeitig ein Blick in die OpenGL ES 1.1 Reference Pages
[OPENGLESDOC] (sehr ausführliche Beschreibung der C Funktionen von OpenGL ES) oder in die
Java-Doc des „Java Binding for the OpenGL ES“ [JOGLESDOC] zu empfehlen.
Zur Realisierung von OpenGL Programmen werden gerne Funktionen der OpenGL Utility Library
(GLU) verwendet. Die GLU erweitert die OpenGL Biliothek um weitere nützliche Funktionen, z.B.
zum Setzen des Augpunktes mit gluLookAt() oder zum Festlegen der Viewing-Volumens mit
gluOrtho2D(). Ein Teil dieser Funktionen ist auch im Android-Framework standardmäßig
implementiert. Zu finden sind die Methoden in der Klasse GLU im Package android.opengl
(siehe Abbildung 3).
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 10
Abbildung 3 Die Klasse GLU und deren Methoden [ANDROIDDOC]
Die zweite in OpenGL Programmen oft verwendete GLUT – Bibliothek (OpenGL Utility Toolkit)
steht in der Android Plattform leider nicht zur Verfügung. GLUT ist ein Fenstersystem, das
unabhängig von der verwendeten Plattform ist. Die Funktionalität wird in Android durch den EGL
Standard übernommen. EGL ist eine Schnittstelle zwischen den Rendering-APIs, wie OpenGL ES
und dem unterliegenden nativen Fenstersystem des Gerätes [EGLSPEC]. EGL stellt Mechanismen
zur Erzeugung des Surfaces und des Contextes zur Verfügung. Das Surface ist ein Container, in den
die Rendering-API hineinzeichnet und der Context sichert den internen Zustand der Rendering-API
[PULLI08]. EGL bietet gegenüber der GLUT den Vorteil, dass es weniger Overhead, also ungenutzte
Funktionen mit sich bringt. Da EGL erneut eine in C definierte Bibliothek darstellt, wird nochmals
eine Wrapperklasse benötigt. Glücklicherweise ist dieser Wrapper bereits in JOGLES integriert,
sodass dieser auch in Android zu Verfügung steht.
Abschließend sollen in diesem Kapitel die Java-Klassen vorstellt werden, die zur Realisierung von
OpenGL ES auf der Android Plattform genutzt werden können. Diese Klassen/Interfaces sind alle
standardmäßig in der Android API integriert.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 11
Package Klasse/Interface Info
javax.microedition.khronos.opengles GL10 Wrapperklasse für OpenGL ES 1.0
Standard
javax.microedition.khronos.opengles GL11 Wrapperklasse für OpenGL ES 1.1
Standard
javax.microedition.khronos.egl EGL10 Wrapper für EGL Standart 1.0
javax.microedition.khronos.egl EGL11 Wrapper für EGL Standart 1.0
android.opengl GLU Android spezifische Umsetzung
einiger Funktionen der GLU
5 Die Entwicklungsumgebung
Um eine Anwendung für Android zu entwickeln, werden diese Entwicklungswerkzeuge benötigt:
� Eclipse Classic / Version 3.4.1 „Ganymede“
Die klassische Entwicklungsumgebung für Java-Anwendungen
Download : http://www.eclipse.org/downloads/
CD – Verzeichnis: /Software/eclipse-3.4.1-win32.zip
� Eclipse Plugin ADT (Android Development Tool) / Version 0.8.0
Erweiterung für die Eclipse IDE mit der besonders einfach und komfortabel Android
Anwendungen entwickelt werden. Mit Hilfe des ADT wird das Android SDK in Eclipse
eingebunden.
Download: http://code.google.com/intl/de-DE/android/adt_download.html
Eclipse-Update-Site: https://dl-ssl.google.com/android/eclipse/
CD – Verzeichnis: /Software/ADT-0.8.0.zip
� Android SDK (Software Development Kit)/ Version 1.0 R2
Im Android SDK Paket ist die wichtige Bibliothek „android.jar“ enthalten und viele weitere
Werkzeuge, wie z.B. der Emulator mit dem die entwickelten Anwendungen direkt auf dem
Entwicklungsrechner getestet werden können. Abgerundet wird das Paket durch eine
Reihe von Beispielprogrammen und einer ausführlichen englischsprachigen
Entwicklerdokumentation.
Download : http://code.google.com/intl/de-DE/android/download_list.html
CD-Verzeichnis : /Software/android-sdk-windows-1.0_r2.zip
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 12
� Die Android Entwickler Dokumentation
Für Android hat Google eine ausführliche englischsprachige Dokumentations-Webseite
erstellt. Auf dieser Webseite findet man das Handwerkszeug zur Programmierung. Das
schon oben genannte SDK und ADT, einige gute Tutorials, Erklärungen zu den Konzepten
und die wichtige Java-Doc des Android-Frameworks.
Webseite (Start): http://code.google.com/intl/de-DE/android/documentation.html
Webseite (Java-Doc): http://code.google.com/intl/de-DE/android/reference/classes.html
CD-Verzeichnis : /BenutzteWebDoku/ANDROIDDOC/docs/index.html
Die Einrichtung dieser Entwicklungsumbebung ist im Anhang Kapitel 10.1 „
Einrichten der Entwicklungsumgebung“ beschrieben.
Noch ein wichtiger Hinweis: Sämtliche Inhalte der Ausarbeitung basieren auf der Android-
Plattform der SDK Version 1.0 R2.
6 Das Tutorial
In diesem Teil der Ausarbeitung soll gezeigt werden, wie OpenGL ES in eine Android Anwendung
integriert werden kann. Um eine möglichst große Vielfalt an OpenGL ES Funktionen zu nutzen,
gibt es im finalen Programm vier verschiedene Tutorials:
T1 - Das Dreieck T2 - Der rotierende Würfel T3 - Pyramide mit Beleuchtung T4 - Würfel mit Textur
Um diese Tutorials nachvollziehen zu können, muss der Leser die Programmiersprache Java
kennen und mit dem Aufbau eines OpenGL (ES) Programms vertraut sein. Des Weiteren sollte der
Leser das Kapitel 10.1.2 „Nutzen der Entwicklungsumgebung“ im Anhang durcharbeiten, wenn er
noch keine eigenen Anwendungen für Android entwickelt hat.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 13
6.1 Tutorial 1 – Das Dreieck
Die Aufgabenstellung für Tutorial 1 ist die Realisierung eines möglichst einfachen OpenGL
Objektes. Hierfür wurde ein Dreieck ausgesucht. Die Herausforderung liegt somit nicht im
OpenGL ES Programm, sondern in der Realisierung der Umgebung für OpenGL ES auf der Android
Plattform. Dies ist gar nicht so einfach und der Umfang der benötigten Codezeilen im Vergleich zu
einem OpenGL Programm, dass mit der GLUT realisiert wird, ist deutlich höher. Dieser
Mehraufwand hängt damit zusammen, dass ein Teil der GLUT Funktionen selbst realisiert werden
muss.
Um zu verstehen, wofür die einzelnen Programmteile benötigt werden, soll zunächst der
Programmablauf der finalen Anwendung vorgestellt werden.
Im Rahmen des „Tutorials 1 – das Dreieck“ wird eine vereinfachte Anwendung entwickelt. Direkt
nach Start der Anwendung wird das gerenderte Dreieck dargestellt. Das Hauptmenü wird nicht
verwendet. Dies erleichtert den ersten Einstieg in die Programmierung von OpenGL ES.
Jetzt kann die Entwicklung des Tutorial 1 starten:
Es wird in Eclipse ein neues Android Projekt erzeugt und mit folgenden Einstellungen konfiguriert.
Das Vorgehen wird in Kapitel 10.1.2.1 „.
1. Starten des Emulators
und Start der Anwendung
„Android OpenGL ES“ im
Menü
2. Hauptmenü erscheint
und per Menü-Taste
werden Tutorials angezeigt
3. Das in OpenGL ES
gerenderte Dreieck wird
dargestellt
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 14
Erstellung eines Projektes“ erklärt.
Automatisch erzeugt Eclipse ein Projekt mit der bekannten Struktur und die Klasse
TutorialOpenGLActivity , die von Activity erbt.
Die Klasse TutorialOpenGLActivity ist also ein Anwendungsbaustein vom Typ Activity
(siehe 3.4 „Aufbau einer Anwendung“). Genau dieser Bausteintyp wird auch für unsere OpenGL
Anwendung benötigt, sodass keine Änderung vorzunehmen ist.
Wenn die Anwendung gestartet wird, wird automatisch die Activity „TutorialOpenGLActivity“
erzeugt. (Dies wird im File AndroidMainfest.xml festgelegt.) Sobald die Activity vom
Framework erzeugt ist, wird die Callback-Methode onCreate() aufgerufen. In dieser Methode
sollte die Initialisierung der Activity erfolgen. Ein wichtiger Initialisierungsschritt ist, das Festlegen
der passenden View.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 15
Für die Darstellung von OpenGL Inhalten wird eine spezielle View benötigt, die SurfaceView. Diese
View stellt uns eine Fläche zur Verfügung, in die mit OpenGL gezeichnet werden kann. Daher wird
jetzt eine neue Klasse erstellt mit dem Namen TutorialBasis, die von SurfaceView erbt.
Der Name TutorialBasis wurde gewählt, da diese Klasse für alle Tutorials die Basis-View sein
soll. Als Schnittstelle wird noch das Interface Surfaceholder.Callback implementiert.
Durch Implementierung dieser Schnittstellte wird die Klasse TutorialBasis vom Android-
Framework über Änderungen der Surfaces informiert.
Nach der Erzeugung erhält man folgendes Gerüst:
package hs.fulda.ai; import android.content.Context; import android.view.SurfaceHolder; import android.view.SurfaceView; public class TutorialBasis extends SurfaceView implements SurfaceHolder.Callback { public TutorialBasis(Context context) { super(context); }
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
} public void surfaceCreated(SurfaceHolder holder) { } public void surfaceDestroyed(SurfaceHolder holder) { } }
Dieses Gerüst der Klasse TutorialBasis wird jetzt sukzessive erweitert mit dem Ziel das
später die drei Methoden
protected abstract void init(GL10 gl);
protected abstract void reshape(GL10 gl, int w, int h); protected abstract void drawFrame(GL10 gl);
aufgerufen werden. Da diese Methoden abstrakt sind, muss auch die Klasse TutorialBasis
abstrakt sein.
public abstract class TutourialBasis extends SurfaceView implements SurfaceHolder.Callback
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 16
Jetzt kann die dritte Klasse erzeugt werden. Diese ist später für die Realisierung der OpenGL ES
Funktionen zuständig. Erzeugung der Klasse T1Dreieck:
package hs.fulda.ai; import javax.microedition.khronos.opengles.GL10; import android.content.Context; public class T1Dreieck extends TutorialBasis{ public T1Dreieck(Context context) { super(context); } protected void drawFrame(GL10 gl) { } protected void init(GL10 gl) { } protected void reshape(GL10 gl, int w, int h) { } }
Da diese von der Superklasse TutorialBasis erbt, müssen die drei Methoden überschrieben
werden. Die Aufgaben der Methoden sind aus den Namen ersichtlich. In der init()- Methode
kann das OpenGL ES Programm initialisiert werden, die Methode reshape() wird aufgerufen,
wenn sich die Fenstergröße auf dem Gerät geändert hat und die Methode drawFrame() wird
immer aufgerufen, wenn ein neues Frame gezeichnet werden soll.
Damit diese Methoden aufgerufen werden, müssen noch einige Änderungen in der Klasse
TutorialBasis vorgenommen werden.
Zunächst Anpassen des Konstruktors:
public TutorialBasis(Context c) { super(c); /*Einrichten der Surface-View in der der OpenGL ES I nhalt *angezeigt wird. */ sHolder = getHolder(); /* * Registrieren, dass diese Klasse * über Surface Änderungen informiert wird */ sHolder .addCallback( this); /* * Setzen der Surface-Typs
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 17
*/ sHolder .setType(SurfaceHolder. SURFACE_TYPE_GPU); }
Und das benötigte Datenfeld einfügen:
protected SurfaceHolder sHolder ; //
Im Anschluss wird die Methode surfaceCreated() angepasst.
/** * Callback - Methode, die vom Surface - Holder aufgerufen wird, * wenn die Surface - View erzeugt wird. * * @param holder Surface - Holder, der die Veränderung feststellte */ public void surfaceCreated(SurfaceHolder holder) { /* * Initialisierung von OpenGL ES durch den EGLHelp er */ gl = eglHelper .initEGL(); /* * Aufruf der überschriebenen init-Methode */ init( gl ); }
eglHelper ist eine Referenz auf ein Objekt der Klasse EGLHelper , die später auch noch
selbst erstellt werden muss. In dieser Klasse wir mit dem nativen EGL, die Schnittstelle zwischen
Fenstersystem von Android und OpenGL ES hergestellt. Die initEGL()- Methode liefert eine
Referenz auf den OpenGL ES 1.0 Context zurück. Mit Hilfe dieses Objektes gl können die
OpenGL ES Funktionen aufgerufen werden.
Folgende Datenfelder müssen angelegt werden:
private EGLHelper eglHelper ;
private GL10 gl ;
Als nächstes wird die Methode surfaceChanged() in der Klasse TutorialBasis angepasst.
Wann die Methode aufgerufen wird, ist dem Methoden-Kommentar zu entnehmen.
/** * Callback - Methode die vom Surface - Holder aufgerufen wird, * wenn sich die Fenstergröße geändert hat. * Zum Beispiel nach der Erzeugung des Surfaces und * wenn das Android - Handset gekippt wurde. * * @param holder Surface - Holder der die Veränderung feststellte * @param format Das neue Format des Surfaces * @param width Die neue Breite des Surfaces * @param height Die neue Höhe des Surfaces */
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 18
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { this. width = width; this. height = height; //Rendern eines Frames renderOneFrame(); }
Und diese neuen Datenfelder werden eingeführt:
private int width ; private int height ;
Natürlich muss als nächstes die Methode renderOneFrame() erstellt werden:
/** * Zuerst Rendern eines Frames mit OpenGL ES und * anschließend D arstellen des Frames auf dem * Geräte - Display */ public void renderOneFrame() { /* * Aufruf der reshape-Methode */ reshape( gl , width , height ); /* * Rendern des nächsten Frames. */ drawFrame( gl ); /* * eglSwapBuffers führt Transfer der Pixel aus dem * EGL/OpenGL ColorBuffer in den Buffer des Geräte - * bildschirms durch. * Tritt ein Fehler bei eglSwapBuffers() wird die * aktuelle Activity beendet. */ if (! eglHelper .eglSwapBuffers()) { Context c = getContext(); if (c instanceof Activity) { ((Activity) c).finish(); } } }
Als letzte Änderung muss in der Klasse TutorialBasis die Methode surfaceDestroyed()
angepasst werden, damit der EGL Context ordnungsgemäß beendet wird.
/** * Callback - Methode die vom Surface - Holder aufgerufen wird, * wenn die Surface - View beendet(=nicht mehr angezeigt) wurde.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 19
* * @param holder Surface - Holder der die Veränderung feststellte */ public void surfaceDestroyed(SurfaceHolder holder) { /* * Ordnungsgemäßes Beenden von EGL */ eglHelper .terminateEGL(); }
Somit wurde die erste Klasse fertig gestellt. Das Ergebnis, die komplette Klasse TutorialBasis
ist im Anhang 10.5.1 „Listing 1: Klasse TutorialBasis“ zu finden.
Wie schon angesprochen, wird jetzt die Klasse EGLHelper erstellt. Der Aufbau dieser Klasse
orientiert sich am Beispielprogramm zu EGL in [PULLI08] auf Seite 242. In den „OpenGL ES 1.1
Reference Pages“ [OPENGLESDOC] findet der interessierte Leser eine ausführliche Dokumentation
der EGL Funktionen. Die Beschreibung der Klasse ist direkt den Kommentaren zu entnehmen.
Da diese Klasse aus über 200 Zeilen Source-Code besteht wurde Sie in den Anhang Kapitel 10.5.2
„Listing 2: Klasse EGLHelper“ verlagert.
Nachdem es möglich ist mit der Klasse EGLHelper den OpenGL ES Context zu erzeugen, kann
mit der Programmierung des eigentlichen OpenGL ES Programms begonnen werden.
Für die Realisierung des Dreiecks werden zwei Arrays in der Klasse T1Dreieck angelegt.
/* Koordinaten für die drei Eckpunkte des Dreiecks * * E2 * X * -- * --- * ---- * ----- * X-----X * E1 E2 * */ float[] triangle = new float[] { -0.25f, -0.25f, 0.0f, //E(ckpunkt) 1 0.25f, -0.25f, 0.0f, //E 2 -0.25f, 0.25f, 0.0f }; //E 3 // Die Farben der Eckpunkte float[] colors = new float[] { 1, 0, 0, 0, //E1 rot 0, 1, 0, 0, //E2 grün 0, 0, 1, 0}; //E3 blau
Leider können diese Arrays nicht direkt für die OpenGL ES Methoden in Java benutzt werden (z.B.
bei glDrawArrays() ). Diese erfordern die Übergabe eines Objektes vom Typ Buffer. Aus
diesem Grund wird eine weitere Klasse erzeugt, welche in einer statischen Methode das float-
Array in den benötigten FloatBuffer (erbt von Buffer ) umwandelt.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 20
package hs.fulda.ai; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.ShortBuffer; /** * Mit Hilfe des BufferGenerators ist es möglich ein normales * Array in einen nativen ByteBuffer umzuwandeln. * * Die Bytebuffer werden benötigt, da nur so die in C geschriebenen Open * GL ES Bibliotheken auf die Daten (die ja in Java abgelegt werden) * zugreifen können. * * @author Christian Klotz * @date 10.12.2008 * @file BufferGenerator.java * */ public class BufferGenerator { /** * Umwandlung eines Float Arrays in einen FloatBuffer
* für Open GL ES * * @param arr Das umzuwandelnde Array * @return fb Referenz auf den erzeugten Floatbuffer * */ public static FloatBuffer makeFloatBuffer( float[] arr) { ByteBuffer bb = ByteBuffer. allocateDirect(arr. length * 4); bb.order(ByteOrder. nativeOrder()); FloatBuffer fb = bb.asFloatBuffer(); fb.put(arr); fb.position(0); return fb; } }
Im Konstruktor der Klasse T1Tutorial werden die Arrays umgewandelt und in zwei neuen
Datenfelder gespeichert.
private FloatBuffer vertexBuff ; private FloatBuffer colorBuff ;
/** * Konstruktor für das Open GL Tutorial1 - Dreieck * * @param c */ public T1Dreieck(Context c) { super(c); vertexBuff = BufferGenerator. makeFloatBuffer( triangle ); colorBuff = BufferGenerator. makeFloatBuffer( colors ); }
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 21
Abschließend werden die drei Methoden der Klasse T1Tutorial mit Inhalt gefüllt. Wie schon in
der Einführung zu OpenGL ES erwähnt, haben die Methoden von OpenGL ES in Java die gleichen
Namen wie die nativen C-Funktionen und bilden deren Funktion ab.
protected void init(GL10 gl) { //Festlegen der Hintergrundfarbe Schwarz gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); //Festlegen das Geraud-Schading verwendet wird gl.glShadeModel(GL10. GL_SMOOTH); }
protected void reshape(GL10 gl, int w, int h) { /*
* Festlegen der Viewing-Ports genauso * groß wie das aktuelle Fenster */
gl.glViewport(0, 0, w, h); /* * Funktion zur Erzeugung der Parallelprojektion = * Festlegung des Viewing-Volumens */ gl.glMatrixMode(GL10. GL_PROJECTION); gl.glLoadIdentity(); /* * Berücksichtigung von Aspekt-Ratio, damit es zu keinen * Verzerrungen kommt. */ if (w <= h) { gl.glOrthof(-1.0f, 1.0f, -1.0f * h / w, 1.0f * h / w,
-2.0f, 2.0f); } else { gl.glOrthof(-1.0f * w / h, 1.0f * w / h, -1.0f, 1.0f,
-2.0f, 2.0f); } //Festlegen des Augpunktes (hier der OpenGL ES Defau lt Wert) GLU. gluLookAt(gl, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f,
0.0f, 1.0f, 0.0f); }
protected void drawFrame(GL10 gl) { //Hintergrundfarbe setzen gl.glClear(GL10. GL_COLOR_BUFFER_BIT); //Modelview - Matrix selektieren gl.glMatrixMode(GL10. GL_MODELVIEW); //Sichern der aktuellen Modelview-Matrix auf dem Sta ck gl.glPushMatrix(); //Skalieren des Dreiecks um Faktor 3 gl.glScalef(3, 3, 0);
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 22
//Aktivierung des Color Arrays und anschließende Zuw eisung gl.glEnableClientState(GL10. GL_COLOR_ARRAY); gl.glColorPointer(4, GL10. GL_FLOAT, 0, colorBuff ); //Aktivierung des Vertex Arrays und anschließende Zu weisung gl.glEnableClientState(GL10. GL_VERTEX_ARRAY); gl.glVertexPointer(3, GL10. GL_FLOAT, 0, vertexBuff ); //Erstellen des Dreiecks gl.glDrawArrays(GL10. GL_TRIANGLES, 0, 3); /* * Wiederherstellen der ursprünglichen Matrix
* Dies ist nötig, da sonst die Transformationsmatri zen * (glScale) miteinander multipliziert werden.
*/ gl.glPopMatrix(); }
Im Anhang 10.5.3 „Listing 3: Klasse T1Dreieck“ kann noch mal die Klasse T1Dreieck
zusammenhängend untersucht werden.
Zu guter Letzt muss der Activity TutorialOpenGLActivity jetzt noch die neu erstellte
OpenGL ES View zugeordnet werden. Aus diesem Grund wird die Zeile:
setContentView( R.layout.main);
in setContentView( new T1Dreieck( this)); geändert.
Mit diesen fünf Klassen wäre die erste Version des Tutorials 1 schon fertig und das Ergebnis kann
im Emulator betrachtet werden. Um den Emulator starten zu können müssen zunächst noch die
„Run Confgurations“ in Eclipse angepasst werden. (siehe 10.1.2.3 "Starten einer Anwendung auf
dem Emulator“).
Nach dem Start des Emulators sollte das mit OpenGL ES gezeichnete Dreieck erscheinen.
Sollte dies nicht funktionieren, wird empfohlen, sich das schon fertige
Eclipse-Projekt zu importieren. Das Eclipse -Projekt zu diesem vereinfachten
Tutorial 1 ist auf der CD im Ordner „/Programme/vereinfachtesTutorial“ zu
finden. Wie der Import eines bestehenden Projektes funktioniert, ist im
Anhang Kaptitel 10.1.2.1 „.
Erstellung eines Projektes / Import eines bestehenden Projektes“
beschrieben.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 23
6.2 Infos zu Tutorials 2, 3 und 4
Leider ist es aufgrund des begrenzten Umfangs dieser Ausarbeitung nicht möglich, auch die
Tutorials „T2 – Das Quadrat“, „T3 – Licht und Material“ und „T4- Textur“ so ausführlich zu
beschreiben wie das Tutorial1.
Daher wird dem interessierten Leser empfohlen direkt in Quellcode zu schauen. Dort sind alle
Tutorials ausführlich dokumentiert und auch der Aufbau der Android GUI (z.B. das Hauptmenü zur
Auswahl der vier Tutorials) wird erklärt.
Um die finale Version des Tutorials anzuschauen, empfehle ich den Import des Eclipse-Projektes.
Das Projekt das alle vier Tutorials mit Hauptmenu und Hilfe enthält ist im Ordner
„/Programme/finalesTutorial“ auf der CD zur Ausarbeitung zu finden.
7 Erkenntnisse der Ausarbeitung
Im diesem Kaptitel sollen die Probleme dargestellt werden, die während der Ausarbeitung
aufgetreten sind. Die Problemlösung nahm oft viel Zeit in Anspruch, deshalb sollen die
Lösungsansätze gleich mit dargestellt werden.
• Programmabstürze auf dem Emulator ohne Fehlermeldungen
Häufig kam es zu Beginn der Entwicklung zu Programmabstürzen im Emulator. Leider
zeigte die normale Eclipse-Console keine Fehlermeldung an und auch die
Fehlermeldungen im Emulator sind nicht aussagekräftig, sodass sich die Suche nach dem
Fehler sehr schwierig gestaltete. Es gibt jedoch mit der Log-Cat Console ein sehr gutes
Werkzeug zur Anzeige von Fehlern im Programmablauf. Dieses Werkzeug ist Teil der
Werkzeugsammlung DDMS (Dalvik Debug Monitor Service) und ist im Anhang 10.1.2.5
„Werkzeuge zum Debuggen und Tools zum Steuern des Emulators“ beschrieben.
• Die neu entwickelte Anwendung startet nicht
Jede Anwendung in Android besteht aus den sogenannten building blocks (vgl. Kap. 3.4
„Aufbau einer Anwendung“ ). Jeder dieser Bausteine muss im File „Mainfest.xml“ (siehe
Kap. 10.1.2.2 „Der typische Aufbau einer Android Anwendung“) definiert werden. Dieses
File wird bei Installation der Anwendung auf dem Emulator/Handset ausgewertet. So
erkennt das Framework, dass eine Anwendung aus den genutzten Komponenten besteht
und welche bei Start der Anwendung ausgeführt wird.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 24
8 Schlusswort
Android stellt eine sehr vielversprechende Softwareplattform für Mobiltelefone dar. Im
Unterschied zu anderen Plattformen verfolgt Android konsequent den „Open Source“-Ansatz,
woraus sich technisch wie kommerziell zahlreiche Vorteile ergeben. [PLEUMANN08]
Durch die Integration von OpenGL ES ist die performante Darstellung von 3D-Inhalten möglich.
Wünschenswert wäre noch die Einbindung der GLUT, die das Entwickeln eigener OpenGL ES
Programme vereinfachen würde.
Mir persönlich hat die Entwicklung auf der Android Plattform jedoch viel Spaß bereitet, da Sie mir
ermöglichte, die Kenntnisse von OpenGL und Java, die mir im Laufe des Studiums vermittelt
wurden, praktisch umzusetzen.
Genau aus diesem Grund möchte ich auch die Android-Plattform zur weiteren Verwendung im
Rahmen von Lehrveranstaltungen an der Hochschule Fulda empfehlen.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 25
9 Quellen
9.1 Literaturverzeichnis
Zum Zeitpunkt der Ausarbeitung gab es fast noch keine Fachliteratur speziell zu Android. Für das
Jahr 2009 sind aber eine Reihe von Neuerscheinungen angekündigt.
[PULLI08] Pulli Kari et al., Mobile 3D Graphics with OpenGL ES und M3G, Morgan
Kaufmann Verlag, 2008
[PLEUMANN08] Dr. Jörg Pleumann, Offenheit prägt künftige Mobiltelefone, erschienen in
Fachzeitschrift Polyscope, Seite18 -19 , 03/2008
http://www.polyscope.ch/dlCenter/ps/2008_3/P03_S18-19.pdf
9.2 Internetquellen
Die Internetadressen wurden am 02.01.2009 auf ihre Gültigkeit hin überprüft. Zusätzlich sind alle
Webseiten auf der CD zur Ausarbeitung im Ordner „/BenutzteWebDoku/[NameDerQuelle]/“ zu
finden.
[ANDROIDANA] Der Aufbau einer Anwendung in Android
http://code.google.com/intl/de-DE/android/intro/anatomy.html
[ANDROIDAUS} Ausarbeitung zu Android von David Staubach, Student an der Universität
Erlangen
https://www4.informatik.uni-
erlangen.de/Lehre/SS08/PS_KVBK/folien/david.staubach-google.android-
ausarbeitung.pdf
[ANDROIDDOC] Offizielle Android Entwickler Dokumentation
http://code.google.com/intl/de-DE/android/documentation.html
[ANDROIDGL] Android OpenGL Tutorial das auf [ZEUSOPENGL] basiert
http://code.google.com/p/android-gl/
[ANDROIDVID] Eine Reihe von Lehrfilmen zum Aufbau von Android und zur Entwicklung
von eigenen Applikationen
http://de.youtube.com/view_play_list?p=586D322B5E2764CF&page=1
[EGLSPEC] Spezifikation von EGL 1.4 durch Khronos Gruppe
http://www.khronos.org/registry/egl/specs/eglspec.1.4.pdf
[EMBEDDEDOS] Marktanteile der Smartphone-Betriebssysteme
http://www.elektronikpraxis.vogel.de/themen/embeddedsoftwareengine
ering/softwarekomponenten/articles/156882/
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 26
[GL10JAVADOC] Java Doc zur OpenGL ES Wrapperklasse GL10
http://code.google.com/intl/de-
DE/android/reference/javax/microedition/khronos/opengles/GL10.html
[JOGLESDOC] Java-Doc von Java Binding for the OpenGL ES
http://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_JCP-
Site/en_US/-/USD/VerifyItem-Start/bindings-1_0-final-
javadoc.zip?BundledLineItemUUID=vUNIBe.plhoAAAEeHz0N1H9y&OrderI
D=jJRIBe.pEz8AAAEeED0N1H9y&ProductID=cJbACUFBDH0AAAEYErI5AXu
Q&FileName=/bindings-1_0-final-javadoc.zip
[JSR239] Spezifikation von Java Binding for the OpenGL ES
http://jcp.org/en/jsr/detail?id=239#orig
[NUTZUNGMOB] Anzahl der weltweit genutzten mobilen Endgeräte
http://www.pcwelt.de/start/mobility_handy_pda/
handy/news/138389/
[NUTZUNGPC] Anzahl der weltweit genutzten PCs
http://www.it-times.de/news/pressemitteilung/datum/
2008/06/23/gartner-zahl-der-weltweit-genutzten-computer-durchbricht-
erstmals-die-milliarden-grenze/
[OHAFAQ] Vorteile von Android für die Mitglieder der OHA
http://www.openhandsetalliance.com/oha_faq.html
[OHAMEMBERS] Mitglieder der Open-Handset-Alliance
http://www.openhandsetalliance.com/oha_members.html
[OHAMEMBERS2] Mitglieder der Open-Handset-Alliance in Tabellenform
http://de.wikipedia.org/wiki/Open_Handset_Alliance
[OPENGLESDOC] OpenGL ES 1.1 Reference Pages
http://www.khronos.org/opengles/sdk/1.1/docs/man/
[SIGGRAPH06] Präsentation auf der Siggraph 2006 zu OpenGL ES und EGL
http://3dshaders.com/s2006/GLES%20and%20EGL.pdf
[TMOBILEG1] Infos zur Einführung vom T-Mobile G1
http://www.teltarif.de/arch/2008/kw50/s32306.html
[ZEUSOPENGL] allgemeines Open GL ES Tutorial der Zeus CMD
http://www.zeuscmd.com/tutorials/opengles/index2.php
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 27
10 Anhang
10.1 Hilfe zur Entwicklungsgebung
10.1.1 Einrichten der Entwicklungsumgebung
Auf den folgenden Seiten wird Schritt-für-Schritt die Installation der Entwicklungsumgebung
erklärt. Diese Beschreibung beschränkt sich auf die Einrichtung unter Windows XP oder Vista. Die
Entwicklung ist aber auch unter Linux und Mac OS X möglich. Ist die Version 3.4 von Eclipse auf
dem Rechner bereits vorhanden, kann Schritt 1 und 2 übersprungen werden. Die in den
Anleitungen angegebenen Pfade stellen Beispiele dar und können natürlich angepasst werden.
An die Hardware des Windows-Entwicklungsrechners werden seitens der eingesetzten Werkzeuge
keine besonderen Anforderungen gestellt. Eine mögliche Umgebung stellt der für die Entwicklung
des Tutorials genutzte Rechner dar:
• Samsung X11 Notebook
• CPU: Intel Core 2 Duo 2x 1,66 GHz
• RAM: 2 GB
• benötigter freier Speicherplatz auf Festplatte : ca. 1 GB
Vorraussetzungen auf dem Entwicklungsrechner schaffen:
1. Um die Entwicklungsumgebung Eclipse nutzen zu können, wird eine aktuelles Java SE
Development Kit (akt. Version 6 Update 11) benötigt. Dieses kann auf der Webseite
http://java.sun.com/javase/downloads/ heruntergeladen werden. Die Installation ist
selbsterklärend.
2. Nach Abschluss des ersten Schritts wird die Installation von Eclipse durchgeführt.
Hierzu muss nur die Datei „eclipse-3.4.1-win32.zip“, die Sie auf der CD im Verzeichnis
„Software“ finden nach „C:/Programme/Eclipse/“ entpackt werden. Zum Abschluss kann
noch eine Verknüpfung auf dem Desktop erstellt werden, die auf die ausführbare
Programmdatei „eclipse.exe“ im Ordner C:/Programme/Eclipse/ zeigt.
Installation der Android Umgebung:
3. Nachdem die Basis gelegt ist, kann die Installation der Android Umgebung beginnen.
Zuerst das Android SDK (android-sdk-windows-1.0_r2.zip) von der CD in den Zielpfad
D:\Android Entwicklung entpacken. Der Inhalt der Ordners sollte so aufgebaut sein:
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 28
Im Ordner „doc“ ist die Entwicklerdokumentation abgelegt, welche sich durch die HTML-
Datei „documentation.html“ einfach aufrufen lässt.
Im Ordner „samples“ finden Sie einige Beispielprogramme mit dazugehörigem Quell-
Code. Diese Beispiele lassen sich mit Eclipse öffnen und auf dem Emulator ausführen.
Dazu gibt es aber später mehr Informationen.
Der Emulator und viele weitere Tools befinden sich im Ordner „tools“. Zugegriffen wird
auf diese Tools via ADT. Im Ordner „usb_driver“ befinden sich Treiber zum Verbinden mit
einem realen Android Gerät.
4. Um das Android SDK und den Emulator in Eclipse zu nutzen, wird jetzt noch das ADT
benötigt. Die Installation des ADT lässt sich am einfachsten durch den in Eclipse
integrierten Software-Manager durchführen. Ein Vorteil ist gleichzeitig, dass man
automatisch über aktuellere Versionen informiert wird. Nachstehend genannte Schritte
sind in Eclipse durchzuführen: (Info: Funktioniert so nur mit Eclipse 3.4)
Aufruf des Software-Managers
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 29
Eine neue Update-Seite hinzufügen:
Eintragen der Download - Seite:
(Info: In Android Dokumenation wird der Link https://dl-ssl.google.com/android/eclipse/
als Update-Site angeben. Dieser funktionierte jedoch nicht, so dass der Link http://dl-
ssl.google.com/android/eclipse/site.xml verwendet wurde. Dieser funktioniert
einwandfrei. )
Mit „OK“ - Bestätigen
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 30
Auswahl und Installation des Android Developer Tool (ADT) und des Android Editors.
Mit „Install“ beginnt die Installation. Die nächsten 2 Schritte sind auf den nächsten 2
Bildern dargestellt.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 31
Abschließend ein Neustart von Eclipse durchführen:
5. Einrichtung des Eclipse-Plugins ADT:
Abschließend muss noch die Verknüpfung zwischen ADT und dem Android SDK hergestellt
werden. Da ADT die Tools des SDK, wie z.B. den Emulator steuert.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 32
Öffnen der Eclipse – Einstellungen:
In den Reiter „Android“ wechseln:
Eintragen des Pfades, an dem das Android SDK entpackt wurde. Abschließend mit „OK“
bestätigen.
Somit ist die Einrichtung der Entwicklungsumgebung abgeschlossen.
10.1.2 Nutzen der Entwicklungsumgebung
In diesem Abschnitt der Ausarbeitung soll an einem einfachen „Hello World“ Programm die
nötigen Entwicklungschritte einfach und verständlich erklärt werden.
10.1.2.1 Erstellung eines Projektes / Import eines bestehenden Projektes
Der Import eines bestehenden anderen Android-Projektes (z.B. von der CD zur Ausarbeitung)
sollte auch auf diese Weise durchgeführt werden.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 33
Wie gewöhnlich kann ein Projekt in Eclipse über File -> New -> Project angelegt werden. Nach der
Installation des ADT erscheint eine neue Projektart: Das Android Projekt.
Diese Projektart wird ausgewählt und das Projekteinstellungsmenü erscheint. Für diese erste
Einführung wird das von der Android Community erstellte Programm „HelloAndroid“ verwendet.
Dieses Projekt ist eines der Beispielprogramme, die im Android SDK enthalten sind. Um dieses zu
öffnen, müssen diese Einstellungen vorgenommen werden:
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 34
1. Auswählen, dass ein vorhandenes Projekt benutzt wird.
2. Angabe des Pfads <InstallationspfadAndroidSDK>\samples\HelloActivity
Wenn gewünscht, kann noch der Projektname oder der Applikationsname geändert werden.
3. Abschließen der Einstellung und Erstellung des Projektes
Dieses Vorgehen ist bei der Erstellung eines eigenen neuen Projektes identisch. Was noch zu
Beginn für Verwirrung sorgt, sind die 4 verschiedenen Namen, die angegeben werden müssen:
• Projektname = der Name des Eclipse Projekts
• Package name = Paketstruktur des Projektes in Eclipse
• Activity name = Name der Hauptklasse, diese Klasse erbt von der Klasse Activity und ist
der spätere Start in die Anwendung
• Application name = Name der Anwendung, der auf dem Gerät angezeigt wird. z.B. als Titel
des Fensters oder als Verknüpfungsname
So schnell und einfach ist die Erstellung eines Projektes möglich.
10.1.2.2 Der typische Aufbau einer Android Anwendung
Nach der Erzeugung eines Projektes wird eine Ordnerstruktur generiert.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 35
Der Source Code wird, wie in den Einstellungen angegeben, in einem Package abgelegt. In dem
Package befinden sich 2 Java-Dateien. Die „HelloActivity.java“ ist der Einstiegspunkt in die
Anwendung. Ist also vergleichbar mit der Main-Klasse in einem klassischen Javaprogramm. Die
Klasse „R.java“ ermöglicht einen einfachen Zugriff auf die im Ordner „res“ definierten Ressourcen.
Im Ordner „res“ werden die Ressourcen der Anwendung gespeichert. Das können Bilder oder
Icons sein, diese befinden sich im Ordner „drawable“. Im Ordner-„layout“ wird das Layout der
Views (= Aussehen der Anwendung) definiert. Man kann GUIs nicht nur in Java-Code erstellen,
wie z.B. von klassischen Swing GUIs gewohnt, sondern es ist auch möglich eine View mittels XML
zu definieren, was sehr der Definition des Layouts einer HTML Seite via CSS ähnelt. Man kann hier
erkennen, dass neue Konzepte eingeführt werden, um die Entwicklung zu vereinfachen. Im
Ordner „values“ sollten alle Inhalte der Views abgelegt werden, also der eigentlich Content einer
View. Durch dieses Konzept wird der Inhalt vom Layout getrennt.
Das File „AndroidMainfest.xml“ wird von jeder Anwendung benötigt und muss sich direkt im
Hauptordner des Projektes befinden. Durch diese Datei werden die globalen Einstellungen der
Anwendung im Android-Framework festgelegt. So wird z.B. festgelegt, welche verschiedenen
„Activitys“ es innerhalb der Anwendung gibt und welche zu Beginn gestartet werden soll.
Nachdem wir uns mit der Ordnerstruktur beschäftig haben, werfen wir einen kurzen Blick auf das
Java-Programm „HelloActivity.java“:
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 36
Dies ist sehr einfach aufgebaut. Es gibt die Klasse HelloActivity , welche von Activity
erbt. Vom Android System wird automatisch bei Start der Activity die Callback-Methode
onCreate() aufgerufen. Dort wird mit
setContentView(R.layout.hello_activity) der Activity die View
“hello_activity.xml” zugeordnet. Diese ist im Ordner res abgelegt:
Diese View kann mit Hilfe des Android Layout Editors erstellt/angesehen und in einer Vorschau
kontrolliert werden (Rechte Maustaste auf hello_activity.xml �Open With � Android Layout
Editor):
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 37
Der Inhalt der View „hello_activity“ ist ein editierbares Textfeld. Für dieses Textfeld wird eine ID
definiert, mit der der Zugriff aus dem Java-Programm auf dieses Textfeld möglich ist (R.id.text).
Die nächsten Attritbute des Tags „EditText“ beschreiben das Layout des Textfelds, wie z.B. Breite
und Höhe. Am Ende wird mit „android:text=“ die Verknüpfung zum Inhalt hergestellt. In der Datei
„strings.xml“ wird der Inhalt der Android-Views abgelegt.
Mit „@string“ wird auf diese Datei zugegriffen und dort der String „hello_activity_text_text“
selektiert. Inhalt des Stings ist „Hello, World!“.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 38
Nach der Erstellung der View in XML kann auch gleich eine Vorschau angezeigt werden. Ein
Umschalten zwischen XML-Ansicht und Layout ist auf den Reitern links unten möglich.
Achtung: Im Laufe der Entwicklung wurde festgestellt, dass die Layoutvorschau nicht immer
einwandfrei funktioniert. Z.B. werden Bilder nicht korrekt skaliert. Folglich sollte das Layout der
View immer in der späteren Anwendung auf dem Emulator getestet werden.
10.1.2.3 Starten einer Anwendung auf dem Emulator
Zunächst muss einmalig die Eclipse Ablaufumgebung angepasst werden.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 39
Im Anschluss sollten diese Einstellungen durchgeführt werden:
Durch „Run“ wird der Emulator gestartet. Diese Konfiguration muss nur einmalig durchgeführt
werden.
Bei den nächsten Starts muss nur noch „Hello_Activity“ selektiert werden.
Nach kurzer Zeit erscheint der Emulator und die entwickelte Anwendung wird gestartet.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 40
10.1.2.4 Bedienung des Emulators
Die Bedienung des Emulators ist einfach und ähnelt der Bedienung eines Handys. Eine
Besonderheit gibt es jedoch, man kann das Gerät auch kippen und der Bildschirm dreht sich
automatisch mit. Dies ist möglich durch die Tastaturkombination „STRG+7“.
10.1.2.5 Werkzeuge zum Debuggen und Tools zum Steuern des Emulators
Die „HelloWorld“ Anwendung funktioniert auf Anhieb. Leider ist das bei der Entwicklung von
eigenen Programmen oft nicht der Fall. Deshalb stellt das Android SDK eine Reihe von Tools zur
Verfügung, mit denen es möglich ist Fehler zu finden.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 41
Zum einen ist es möglich den Eclipse Debugger zu verwenden. Dieser lässt sich genauso bedienen
wie beim Debugging eines normalen Java-Programms. Zuerst einen Stopppunkt setzen und
anschließend den Emulator im Debug-Modus ( = ) starten.
Ein komplett neu entwickeltes Werkzeug ist der „Dalvik Debug Monitor Service“ (DDMS). Dieses
Tool vereint eine Reihe von Funktionen:
Der File-Explorer dient zur Ansicht der Dateien auf dem Emulator.
Die Darstellung von Systeminformationen über die Prozesse, Threads und Aufbau es aktuellen
Heaps im Gerät ist möglich.
Mit dem Emulator Controller können externe Ereignisse, wie eine eingehende SMS, simuliert
werden.
Das wichtigste Tool für Entwickler ist jedoch die „LogCat“-Console. Auf dieser Konsole werden
sämtliche Informationen des Andriod Emulators ausgeben. Auch Fehlermeldungen werden hier
und nicht auf der Standard-Eclipse-Console dargestellt.
10.2 Anwenderdokumentation
In diesem Kapitel soll erklärt werden, wie das finale Tutorial auf dem Emulator bedient wird. Die
Bedienung ist sehr einfach gehalten und fast schon selbsterklärend.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 42
1. Starten des Emulators
und Start der Anwendung
„Android OpenGL ES“ im
Hauptmenü von Android
2. Hauptmenü des
Andorid OpenGL Tutorials
wird angezeigt. Per Menü-
Taste klappt das
Auswahlmenü auf
3. Auswahl des
gewünschten Tutorials /
OpenGL Objektes
4. Das entsprechende
Tutorial wird angezeigt.
z.B. T3 die Pyramide
z.
5. Per erneuten Druck
auf die Menü-Taste wird
folgendes Optionsmenü
angezeigt.
6. Anzeige der Hilfe
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 43
10.3 Darstellung des Aufwandes
Art des Aufwandes Stunden
Informationsbeschaffung 18
Informationsaufarbeitung 22
Programmierarbeit 22
Dokumentation Quelltext 9
Fehlersuche im Programm 8
Präsentation 15
Ausarbeitung 55
Gesamt 149
7. Anzeigen der Option
„Licht aus“
8. Verlassen einer Ansicht
Jede Ansicht kann durch
den „Zurück“ – Button
verlassen werden.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 44
Verteilung der Aufwandes
Informationsbeschaffung
Informationsaufarbeitung
Programmierarbeit
Dokumentation Quelltext
Fehlersuche im Programm
Präsentation
Ausarbeitung
10.4 Aufbau der CD zur Ausarbeitung
Auf der CD zur Ausarbeitung gibt es diese Verzeichnisse:
Im Verzeichnis
• Arbeit befindet sich die digitale Version dieser Ausarbeitung.
• BenutzeWebDoku sind die digitalen Quellen (Webseiten) dieser Ausarbeitung
gesichert.
• Präsentation befindet sich die Präsentation zur Ausarbeitung.
• Programme ist der Quell-Code der Tutorials abgelegt. Es gibt zwei verschiedene
Versionen, die je als Eclipse-Projekt abgelegt wurden. Das vereinfachte Tutorial
realisiert nur ein Dreieck mit OpenGL ES (ausführlich in Kapitel 6.1 beschieben). Die
finale Version des Tutorials ist eine überarbeitete und aufwendigere Version mit
Umsetzung von vier verschiedenen Tutorials.
• Software sind die benötigten Entwicklungswerkzeuge abgelegt. Wie diese installiert
und konfiguriert werden, ist im Kapitel 10.1 zu finden.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 45
10.5 Source-Code zum Tutorial 1
Auf den folgenden Seiten wird der Quellcode der vereinfachten Tutorials abgebildet.
Zum Überblick ein Klassendiagramm, das die Struktur der Klassen darstellt.
Der Source-Code ist auch auf der CD im Ordner „Programme\vereinfachtesTutorial\
\src\hs\fulda\ai“ zu finden.
10.5.1 Listing 1: Klasse TutorialBasis
package hs.fulda.ai; import javax.microedition.khronos.opengles.GL10; import android.app.Activity; import android.content.Context; import android.view.SurfaceHolder; import android.view.SurfaceView; /** * TutorialBasis ist die Basis für eine OpenGL ES Anwendung unter Android. * Sie erbt von der Klasse SurfaceView, mit der es möglich ist OpenGL ES * Inhalte darzustellen. * * @author Christian Klotz * @date 1.1.2009 * @file TutourialBasis.java * */ public abstract class TutorialBasis extends SurfaceView implements SurfaceHolder.Callback { protected SurfaceHolder sHolder ; private EGLHelper eglHelper ; private int width ; private int height ;
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 46
private GL10 gl ; /** * Konstruktor für die Klasse TutourialBasis * Es wird versucht die angegebene Anzahl an Frames zu
* realisieren. * * @param c Der Android Context der Anwendung * @param fps Die gewünschte Anzahl von Frames pro Sekunde */ public TutorialBasis(Context c) { super(c); /*Einrichten der Surface-View in der der OpenGL ES I nhalt *angezeigt wird. */ sHolder = getHolder(); /* * Registrieren das diese Klasse * über Surface Änderungen informiert wird */ sHolder .addCallback( this); /* * Setzen der Surface-Typs */ sHolder .setType(SurfaceHolder. SURFACE_TYPE_GPU); eglHelper = new EGLHelper( sHolder ); } /** * Callback - Methode die vom Surface - Holder aufgerufen wird, * wenn die Surface - View erzeugt wird. * * @param holder Surface - Holder der die Veränderung feststellte */ public void surfaceCreated(SurfaceHolder holder) { /* * Initialisierung von OpenGL ES durch den EGLHelp er */ gl = eglHelper .initEGL(); /* * Aufruf der überschriebenen init-Methode */ init( gl ); } /** * Callback - Methode die vom Surface - Holder aufgerufen wird, * wenn sich die Fenstergröße geändert hat. * Wird aufgerufen nach der Erzeugung des Surfaces und * wenn Android - Handy gekippt wird. * * @param holder Surface - Holder der die Veränderung feststellte * @param format Das neue Format des Surfaces * @param width Die neue Breite des Surfaces * @param height Die neue Höhe des Surfaces */
public void surfaceChanged(SurfaceHolder holder, int format, int
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 47
width, int height) { this. width = width; this. height = height; //Starten des OpenGL Threads zum Rendern renderOneFrame(); } /** * Callback - Methode die vom Surface - Holder aufgerufen wird, * wenn die Surface - View beendet wurde. * * @param holder Surface - Holder der die Veränderung feststellte */ public void surfaceDestroyed(SurfaceHolder holder) { /* * Ordnungsgemäßes Beenden von EGL */ eglHelper .terminateEGL(); } /** * Zuerst Rendern eines Frames mit OpenGL ES und * anschließend Darstellen des Frames auf dem * Geräte - Display */ public void renderOneFrame() { /* * Aufruf der reshape-Methode */ reshape( gl , width , height ); /* * Rendern des nächsten Frames. */ drawFrame( gl ); /* * eglSwapBuffers führt Transfer der Pixel aus dem * EGL/OpenGL ColorBuffer in den Buffer des Geräte * Bildschirms durch. * Tritt ein Fehler bei eglSwapBuffers() wird die * aktuelle Activity beendet. */ if (! eglHelper .eglSwapBuffers()) { Context c = getContext(); if (c instanceof Activity) { ((Activity) c).finish(); } } } /** * Die Methode init() muss von der erbenden Klasse implementiert
* werden. * Methode wird einmalig bei Start der Anwendung aufgerufen, und * dient zur Initialisierung von Open GL Zustandsmaschine.
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 48
* * @param gl Der Open GL Context * @param w Aktuelle Breite der Fensters * @param h Aktuelle Höhe des Fensters */ protected abstract void init(GL10 gl); /** * Die Methode reshape() muss von der erbenden Klasse implementiert
* werden. * Methode wird aufgerufen, wenn sich Fenstergröße geändert hat. * * @param gl Der Open GL Context * @param w Aktuelle Breite der Fensters * @param h Aktuelle Höhe des Fensters */ protected abstract void reshape(GL10 gl, int w, int h); /** * Die Methode drawFrame muss von der erbenden Klasse implementiert
* werden. * Methode wird aufgerufen, wenn das Frame neu gezeichnet werden
* soll. * Dieser Aufruf tritt so oft auf, wie im Konstruktor mit fps
* e ingestellt. * * @param gl Der Open GL Context * @param w Aktuelle Breite der Fensters * @param h Aktuelle Höhe des Fensters */ protected abstract void drawFrame(GL10 gl); }
10.5.2 Listing 2: Klasse EGLHelper
package hs.fulda.ai; import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGL11; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLContext; import javax.microedition.khronos.egl.EGLDisplay; import javax.microedition.khronos.egl.EGLSurface; import javax.microedition.khronos.opengles.GL10; import android.view.SurfaceHolder; /** * Klasse, die das Handling der EGL Schnittstelle durchführt. * * EGL ist Schnittstelle zwischen OpenGL ES und dem Window- System * von Android * * @author Christian Klotz * @date 12.12.2008 * @file EGLHelper.java * */ public class EGLHelper
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 49
{ /* * Die benötigten EGL Objekte */ private EGL10 egl ; private EGLContext glesContext ; private EGLSurface glesSurface ; private EGLDisplay glesDisplay ; protected SurfaceHolder sHolder ; /** * Konstruktor für den EGLHelper * * @param sHolder Der EGLHelper benötigt den dazugehörigen * SurfaceHolder */ public EGLHelper(SurfaceHolder sHolder) { this. sHolder = sHolder; } /** * Initialisierung der EGL Schnittstelle * EGL ist Schnittstelle zwischen OpenGL ES und dem Windows * - System von Android * * @return Referenz auf den OpenGLES 1.0 Context */ public GL10 initEGL() { /* * Erzeugen einer EGL Instanz */ egl = (EGL10) EGLContext. getEGL(); /* * Erhalten des Standard Displays */ glesDisplay = egl .eglGetDisplay(EGL10. EGL_DEFAULT_DISPLAY); /* * Initialisierung der EGL Instanz */ int[] version = new int[2]; egl .eglInitialize( glesDisplay , version); /* * Definition der Konfiguration */ int[] configSpec = { EGL10. EGL_RED_SIZE, 8, EGL10. EGL_GREEN_SIZE, 8, EGL10. EGL_BLUE_SIZE, 8, EGL10. EGL_DEPTH_SIZE, 16, EGL10. EGL_NONE }; /* * Mögliche Konfiguration ermitteln. Es wird durch EGL * geprüft, ob die oben angegebene Konfiguration r ealisiert * werden kann. * * Liefert die mögliche Konfiguration "config" zur ück
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 50
*/ EGLConfig[] configs = new EGLConfig[1]; int[] num_config = new int[1]; egl .eglChooseConfig( glesDisplay , configSpec, configs, 1, num_config); EGLConfig config = configs[0]; /* * Erstellung des OpenGL ES Contextes. Der Context ist ein * Container, der den gesamten internen Zustand * (z.B. akt. Matrix-Stack, Textur Objekte,..) von OpenGL ES * enthält. */ glesContext = egl .eglCreateContext( glesDisplay , config, EGL10. EGL_NO_CONTEXT, null); /* * Erstellung eines EGL Surfaces. * Das Surface ist ein Container, der die gerender ten Pixel * enthält. Diese Pixel werden auch gleichzeitig a uf dem * Geräte-Display dargestellt. *
* Hier wird auch die Verknüpfung zum Android Fenster *hergestellt,
* da eine Referenz auf den SurfaceHolder mit über geben wird. */ glesSurface = egl .eglCreateWindowSurface ( glesDisplay , config, sHolder , null); /* Noch vor der Verwendung einer OpenGL ES Funktion, * muss der Context an das Surface gebunden werden und * dieser Context aktiv gesetzt werden. */ egl .eglMakeCurrent ( glesDisplay , glesSurface , glesSurface , glesContext ); /* * Rückgabe des GL10 Referenz * Mit diesem können alle OpenGL ES Operationen au f dem * EGL Context ausgeführt werden. */ return ((GL10) glesContext .getGL()); } /** * Beenden der EGL Schnittstelle und Freigabe genutzter Ressourcen */ public void terminateEGL() { /* * Prüfen, ob EGL mit initEGL initialisiert wurde. */ if ( glesSurface != null && egl != null && glesContext != null && glesDisplay != null) { /* * Die Verbindung zwischen EGL Context und Surface entfernen * und anschließend den Context deaktivieren. */ egl .eglMakeCurrent( glesDisplay , EGL10. EGL_NO_SURFACE, EGL10. EGL_NO_SURFACE, EGL10. EGL_NO_CONTEXT);
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 51
/* * Zerstören des Surfaces */ egl .eglDestroySurface( glesDisplay , glesSurface ); /* * Zerstören des OpenGL ES Contextes */ egl .eglDestroyContext( glesDisplay , glesContext ); /* * Das EGL Display beenden */ egl .eglTerminate( glesDisplay ); /* * Ressourcen freigeben */ glesSurface = null; glesContext = null; glesDisplay = null; egl = null; } } /** * Darstellung der gerenderten Pixel auf Display. * * Führt Transfer der Pixel aus dem EGL/OpenGL ColorBuffer * in den Buffer des Geräte Bildschirms durch. * * @return bool : true = Swap der Bufffer erfolgreich <br> * false = nicht erfolgreich */ public boolean eglSwapBuffers() { egl .eglSwapBuffers( glesDisplay , glesSurface ); /* * Prüfen ob Context noch vorhanden. * Context kann verloren werden, wenn Gerät in Sch lafmodus * übergeht. * * Dann muss Activity neu gestartet werden. */ return !( egl .eglGetError() == EGL11. EGL_CONTEXT_LOST); } }
10.5.3 Listing 3: Klasse T1Dreieck
package hs.fulda.ai; import java.nio.FloatBuffer; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.opengl.GLU;
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 52
/** * Das erste Tutorial aus der Reihe OpenGL ES auf Android * * Hier soll ein einfaches Dreieck auf dem Bildschirm dargestellt * werden. * Die Echpunkte besitzen je eine andere Farbe und es wird Geraud - Shading * (= Smooth - Shading) verwendet, um einen Farbverlauf zu erhalten. * * Das Tutorial 1 benötigt die Klasse TutorialBasis, * in der die Grundlagen einer OpenGL ES Applikation * realisiert werden. * BufferGenerator.java * @author Christian Klotz * @date 07.12.2008 * */ public class T1Dreieck extends TutorialBasis { /* Koordinaten für die drei Eckpunkte des Dreiecks * * E2 * X * -- * --- * ---- * ----- * X-----X * E1 E2 * */ private float[] triangle = new float[] { -0.25f, -0.25f, 0.0f, //E(ckpunkt) 1 0.25f, -0.25f, 0.0f, //E 2 -0.25f, 0.25f, 0.0f }; //E 3 // Die Farben der Eckpunkte private float[] colors = new float[] { 1, 0, 0, 0, //E1 rot 0, 1, 0, 0, //E2 grün 0, 0, 1, 0}; //E3 blau /* * Die Open GL ES Funktionen benötigen als Übergabe -Parameter kein * normales Array sondern ein Buffer (java.nio.Buff er). * Daher müssen die Arrays triangle und colors in F loatBuffer
* umgewandelt werden. * Siehe Konstruktor */ private FloatBuffer vertexBuff ; private FloatBuffer colorBuff ; /** * Konstruktor für das Open GL Tutorial1 - Dreieck * * @param c */ public T1Dreieck(Context c) { super(c); vertexBuff = BufferGenerator. makeFloatBuffer( triangle ); colorBuff = BufferGenerator. makeFloatBuffer( colors ); }
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 53
/** * In der Init - Methode kann die Initialisierung * der OpenGL ES Anwendung erfolgen. * Diese Methode wird automatisch von der Kasse * TutorialBasis bei Programmstart aufgerufen. * * @param gl Übergabe des aktuellen OpenGL Contextes * */ @Override protected void init(GL10 gl) { //Festlegen der Hintergrundfarbe Schwarz gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); //Festlegen das Geraud-Schading verwendet wird gl.glShadeModel(GL10. GL_SMOOTH); } /** * Diese Methode wird automatisch von der Klasse TutorialBasis * aufgerufen, wenn sich die Fenstergröße geändert hat. * Dies tritt z.B. bei Drehen des Gerätes auf. * * @param gl Übergabe des aktuellen OpenGL Contextes * @param w Breite des Fensters in Pixel * @param h Hoehe des Fensters in Pixel * */ @Override protected void reshape(GL10 gl, int w, int h) { /*
* Festlegen der Viewing-Ports genauso groß wie das aktuelle * Fenster */
gl.glViewport(0, 0, w, h); /* * Funktion zur Erzeugung der Parallelprojektion = * Festlegung des Viewing-Volumens */ gl.glMatrixMode(GL10. GL_PROJECTION); gl.glLoadIdentity(); /* * Berücksichtigung von Aspekt-Ratio, damit es zu keinen * Verzerrungen kommt. */ if (w <= h) { gl.glOrthof(-1.0f, 1.0f, -1.0f * h / w, 1.0f * h / w,
-2.0f, 2.0f); } else { gl.glOrthof(-1.0f * w / h, 1.0f * w / h, -1.0f, 1.0f,
-2.0f, 2.0f); } //Festlegen des Augpunktes (hier der OpenGL ES Defau lt Wert) GLU. gluLookAt(gl, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f,
0.0f, 1.0f, 0.0f);
Christian Klotz 07.01.2008
Android & OpenGL ES Seite 54
} /** * Diese Methode wird automatisch von der Klasse TutorialBasis
* aufgerufen, * wenn das Frame/das Objekt neu gezeichnet werden soll. * * Wie oft diese Methode aufgerufen wird, ist * abhängig von der im Konstruktor angegebenen Framerate. * * @param gl Übergabe des aktuellen OpenGL Contextes * */ @Override protected void drawFrame(GL10 gl) { //Hintergrundfarbe setzen gl.glClear(GL10. GL_COLOR_BUFFER_BIT); //Modelview - Matrix selektieren gl.glMatrixMode(GL10. GL_MODELVIEW); //Sichern der aktuellen Modelview-Matrix auf dem Sta ck gl.glPushMatrix(); //Skalieren des Dreiecks um Faktor 3 gl.glScalef(3, 3, 0); //Aktivierung des Color Arrays und anschließende Zuw eisung gl.glEnableClientState(GL10. GL_COLOR_ARRAY); gl.glColorPointer(4, GL10. GL_FLOAT, 0, colorBuff ); //Aktivierung des Vertex Arrays und anschließende Zu weisung gl.glEnableClientState(GL10. GL_VERTEX_ARRAY); gl.glVertexPointer(3, GL10. GL_FLOAT, 0, vertexBuff ); //Erstellen des Dreiecks gl.glDrawArrays(GL10. GL_TRIANGLES, 0, 3); /* * Wiederherstellen der ursprünglichen Matrix * Dies ist nötig, da sonst die Transformationsmat rizen (glScale) * miteinander multipliziert werden. */ gl.glPopMatrix(); } }