54
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

HS Fulda – Fachbereich Angewandte Informatik Analyse und ... OpenGLE… · • Broadcom Corporation ... • LG • Motorola •

  • Upload
    lytram

  • View
    221

  • Download
    0

Embed Size (px)

Citation preview

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

werner
Durchstreichen

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

• Google

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