Android inclou suport per a alt rendiment en 2D i gràfics 3D amb la biblioteca de gràfics oberta (OpenGL), en concret, l'API OPENGL és una API de gràfics de plataforma creuada que especifica una interfície de programari estàndard per al maquinari de procés de gràfics 3D. OPENGL és una adaptació de l'especificació OpenGL destinada a dispositius encastats.
Android és compatible amb diverses versions de l'API OpenGL.
És una API que especifica com es fan els models 3D... hi ha un jugador que mira al món, tot està compost per triangles, les matrius de treball estan perfectament definides, forma part de Kronos, ho van fer per als sistemes 3D.
Kronos és una fundació amb ànim de lucre, tot és lliure però guanyen diners pel hardware. Es va crear en llenguatge C, és d'estat seqüencial i treballa matricialment, era un C sense complicacions perquè estava pensat per a codi màquina. La gràcia és que l'algorisme de càlcul d'una superfície el pot fer o bé el hardware i si aquest no ho té implementat ho fa el software.
Així doncs, si tens un programa que ha de fer il·luminació, cal tenir en compte que el hardware és molt més ràpid que utilitzar el software.
Hi ha diverses versions, aquestes fan referència a l'OpenGL per a dispositius mòbils, el WebGL és amb JavaScript amb navegador i únicament OpenGL per als PC de sobretaula, com Windows, Linux, Apple...
Les diferents i més rellevants versions d'OpenGL serien:
- OpenGL ES 1.0 i 1.1 - especificació API amb suport d'Android 1.0 i superior.
- OpenGL ES 2.0 - especificació API suportat per Android 2.2 (nivell d'API 8) 4.3 i superior.
- OpenGL ES 3.0 - especificació API amb suport per a Android (nivell d'API 18) 4.3 i superior.
L'API específica proporcionada per Android és similar a l'API J2ME JSR239 OpenGL ES, però no és idèntica.
Hi ha dues classes fonamentals a Android que et permeten crear i manipular gràfics amb l'API OpenGL ES:
- GL.SurfaceView.
- GL.SurfaceView.Renderer.
GL.SurfaceView
Aquesta classe és una View on es pot dibuixar i manipular objectes mitjançant crides a l'API d'OpenGL i és similar en funció a un . Es pot utilitzar aquesta classe mitjançant la creació d'una instància de GLSurfaceView i afegint-hi el seu Renderer. No obstant això, si volem capturar desenvolupaments de pantalla tàctil, s'ha d'ampliar la classe GLSurfaceView per implementar els oients tàctils.
El GLSurfaceView és una vista especial que gestiona superfícies OpenGL per a nosaltres i dibuixa en el sistema de visió d'Android. També afegeix una gran quantitat de característiques que fan que sigui més fàcil d'utilitzar OpenGL, incloent-hi però no limitat a:
- Proporciona un subprocés de representació dedicat per a OpenGL perquè no afecti el fil principal.
- Ens permet dibuixar quan vulguem.
- S'ocupa de la configuració de pantalla per a nosaltres, utilitzant EGL, la interfície entre OpenGL i el sistema de finestres subjacent.
Essencialment tindrem una vista, igual que tenim botons, imatges i textView, tindrem un GLSurfaceView, tot el que es dibuixi allà anirà per hardware. Per utilitzar OpenGL es recomanen les API de Java, OpenGL està especificat en C, però són càlculs matricials, per tant no hi ha centenars de línies de codi, sinó que són productes transformats que es poden portar a qualsevol llenguatge de programació. Amb qualsevol llenguatge de programació ho pots fer.
GLSurfaceView.Renderer
Aquesta interfície defineix els mètodes necessaris per dibuixar gràfics en un GLSurfaceView. S'ha de proporcionar una implementació d'aquesta interfície amb una classe separada i adjuntar-la a la instància GLSurfaceView utilitzant GLSurfaceView.setRenderer().
Requereix que implementi els mètodes següents:
- onSurfaceCreated(): El sistema crida aquest mètode una vegada, en crear el GLSurfaceView. Utilitzeu aquest mètode per dur a terme accions que han d'ocórrer només una vegada, com configurar els paràmetres de l'entorn OpenGL o la inicialització d'objectes gràfics OpenGL.
- onDrawFrame(): El sistema crida aquest mètode en cada redibuix del GLSurfaceView. Utilitzeu aquests mètodes com a principal punt d'execució per elaborar (i redibuixar) objectes gràfics.
- onSurfaceChanged(): El sistema crida aquest mètode quan el GLSurfaceView canvia de geometria, incloent-hi canvis en la mida del GLSurfaceView o l'orientació de la pantalla del dispositiu. Per exemple, el sistema crida aquest mètode quan el dispositiu canvia de vertical a horitzontal. Utilitzeu aquest mètode per respondre als canvis en el GLSurfaceView contenidor.
Si l'aplicació utilitza funcions d'OpenGL que no estan disponibles en tots els dispositius, ha d'incloure aquests requisits dins del fitxer AndroidManifest.xml:
<uses-feature android:glEsVersion="0x00020000" android:required="true" /> <uses-feature android:glEsVersion="0x00030000" android:required="true" />
L'API OpenGL ES 3.0 és compatible amb la 2.0, la qual cosa significa que pot ser més flexible amb la seva implementació d'OpenGL ES en l'aplicació. Declarar OpenGL 2.0 és un requisit, i en comprovar la disponibilitat de l'API 3.0 en temps d'execució, si és compatible, utilitzarà aquesta.
Exemple de codi:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mGLSurfaceView = new GLSurfaceView(this); // suporta OpenGL ES 2.0? final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo(); final boolean supportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000; if (supportsEs2){ // context compatible mGLSurfaceView.setEGLContextClientVersion(2); mGLSurfaceView.setRenderer(new NuestroRenderer()); } else{ // Utilitzar OpenGL ES 1, per exemple } //utilitzem tota l'àrea de l'activity setContentView(mGLSurfaceView); }
Abans que el nostre processador mostri alguna cosa, necessitem alguna cosa per mostrar. A OpenGL ES 2, especifiquem matrius de noms. Aquests nombres poden representar posicions, colors, o qualsevol altra cosa. En aquesta demostració mostrarem tres triangles.
// Les dades estan guardades en un buffer de tipus float.
private final FloatBuffer mTriangle1Vertices;
private final FloatBuffer mTriangle2Vertices;
private final FloatBuffer mTriangle3Vertices;
// nombre de bytes per float
private final int mBytesPerFloat = 4;
// Inicialització.
public NuestroRenderer(){
- *final float[] triangle1VerticesData= {
- * // X, Y, Z,
- * // R, G, B, A
- * -0.5f, -0.25f, 0.0f,
- * 1.0f, 0.0f, 0.0f, 1.0f,
- * 0.5f, -0.25f, 0.0f,
- * 0.0f, 0.0f, 1.0f, 1.0f,
- * 0.0f, 0.559016994f, 0.0f,
- *0.0f, 1.0f, 0.0f, 1.0f
- *}
- *// Inicialització dels buffers.
- mTriangle1Vertices = ByteBuffer.allocateDirect(triangle1VerticesData.length mBytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();
- *...
- *mTriangle1Vertices.put(triangle1VerticesData).position(0);
- *...
}
És normal que la codificació sigui en Java a Android, però la implementació interna d'OpenGL ES 2 està escrita en C. Abans de passar les nostres dades per OpenGL, hem de convertir-ho a un format que es pugui entendre. Java i el sistema operatiu natiu podrien no desar els seus bytes en el mateix ordre, així que cal utilitzar un conjunt especial de classes de buffer i crear un ByteBuffer suficientment gran com per mantenir les nostres dades, i dir-li que desi les dades utilitzant l'ordre de bytes natiu. Aleshores els convertim en un FloatBuffer, perquè puguem fer-ho servir per desar les dades de punt flotant. Finalment, copiem la nostra matriu a la memòria intermèdia.