La prima cosa da fare è poter definire le forme da tracciare nel contesto di una visualizzazione OpenGL ES creando grafiche di fascia alta per la tua app. Disegnare con OpenGL ES può essere un po' complicato senza sapendo alcune cose di base su come OpenGL ES si aspetta di definire oggetti grafici.
Questa lezione illustra il sistema di coordinate OpenGL ES relativo allo schermo di un dispositivo Android, nozioni di base per la definizione di una forma e delle facce, nonché per la definizione di triangolo e quadrato.
Definisci un triangolo
OpenGL ES consente di definire gli oggetti disegnati utilizzando le coordinate nello spazio tridimensionale. Quindi,
prima di poter disegnare un triangolo, occorre definirne le coordinate. In OpenGL, il modo tipico
questo serve a definire un array di vertici di numeri in virgola mobile per le coordinate. Per il massimo
efficienza, scrivi queste coordinate in un valore ByteBuffer
, che viene passato all'interno
Pipeline grafica OpenGL ES per l'elaborazione.
Kotlin
// number of coordinates per vertex in this array const val COORDS_PER_VERTEX = 3 var triangleCoords = floatArrayOf( // in counterclockwise order: 0.0f, 0.622008459f, 0.0f, // top -0.5f, -0.311004243f, 0.0f, // bottom left 0.5f, -0.311004243f, 0.0f // bottom right ) class Triangle { // Set color with red, green, blue and alpha (opacity) values val color = floatArrayOf(0.63671875f, 0.76953125f, 0.22265625f, 1.0f) private var vertexBuffer: FloatBuffer = // (number of coordinate values * 4 bytes per float) ByteBuffer.allocateDirect(triangleCoords.size * 4).run { // use the device hardware's native byte order order(ByteOrder.nativeOrder()) // create a floating point buffer from the ByteBuffer asFloatBuffer().apply { // add the coordinates to the FloatBuffer put(triangleCoords) // set the buffer to read the first coordinate position(0) } } }
Java
public class Triangle { private FloatBuffer vertexBuffer; // number of coordinates per vertex in this array static final int COORDS_PER_VERTEX = 3; static float triangleCoords[] = { // in counterclockwise order: 0.0f, 0.622008459f, 0.0f, // top -0.5f, -0.311004243f, 0.0f, // bottom left 0.5f, -0.311004243f, 0.0f // bottom right }; // Set color with red, green, blue and alpha (opacity) values float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f }; public Triangle() { // initialize vertex byte buffer for shape coordinates ByteBuffer bb = ByteBuffer.allocateDirect( // (number of coordinate values * 4 bytes per float) triangleCoords.length * 4); // use the device hardware's native byte order bb.order(ByteOrder.nativeOrder()); // create a floating point buffer from the ByteBuffer vertexBuffer = bb.asFloatBuffer(); // add the coordinates to the FloatBuffer vertexBuffer.put(triangleCoords); // set the buffer to read the first coordinate vertexBuffer.position(0); } }
Per impostazione predefinita, OpenGL ES assume un sistema di coordinate in cui [0,0,0] (X,Y,Z) specifica il centro di
il frame GLSurfaceView
,
[1,1,0] è l'angolo in alto a destra del riquadro e
[-1,-1,0] è l'angolo in basso a sinistra del riquadro. Per un'illustrazione di questo sistema di coordinate, vedere il
Sviluppatore OpenGL ES
.
Tieni presente che le coordinate di questa forma sono definite in ordine antiorario. Il disegno è importante perché definisce quale lato corrisponde alla faccia anteriore della forma, che in genere che desideri tracciare e la faccia posteriore, che puoi scegliere di non disegnare con la modalità OpenGL ES facciale. Per ulteriori informazioni su volti e eliminazione, vedi Guida per gli sviluppatori di OpenGL ES.
Definisci un quadrato
La definizione dei triangoli è abbastanza facile in OpenGL, ma cosa succede se vuoi ottenere complessi? Di', un quadrato? Ci sono molti modi per farlo, ma un percorso tipico per tracciare un in OpenGL ES consiste nell'utilizzare due triangoli disegnati insieme:
Anche in questo caso, devi definire i vertici in ordine antiorario per entrambi i triangoli che
rappresentano questa forma e inserisci i valori in un ByteBuffer
. Per evitare
definendo le due coordinate condivise da ciascun triangolo due volte, utilizza un elenco di disegni per indicare
Pipeline grafica OpenGL ES come disegnare questi vertici. Ecco il codice per questa forma:
Kotlin
// number of coordinates per vertex in this array const val COORDS_PER_VERTEX = 3 var squareCoords = floatArrayOf( -0.5f, 0.5f, 0.0f, // top left -0.5f, -0.5f, 0.0f, // bottom left 0.5f, -0.5f, 0.0f, // bottom right 0.5f, 0.5f, 0.0f // top right ) class Square2 { private val drawOrder = shortArrayOf(0, 1, 2, 0, 2, 3) // order to draw vertices // initialize vertex byte buffer for shape coordinates private val vertexBuffer: FloatBuffer = // (# of coordinate values * 4 bytes per float) ByteBuffer.allocateDirect(squareCoords.size * 4).run { order(ByteOrder.nativeOrder()) asFloatBuffer().apply { put(squareCoords) position(0) } } // initialize byte buffer for the draw list private val drawListBuffer: ShortBuffer = // (# of coordinate values * 2 bytes per short) ByteBuffer.allocateDirect(drawOrder.size * 2).run { order(ByteOrder.nativeOrder()) asShortBuffer().apply { put(drawOrder) position(0) } } }
Java
public class Square { private FloatBuffer vertexBuffer; private ShortBuffer drawListBuffer; // number of coordinates per vertex in this array static final int COORDS_PER_VERTEX = 3; static float squareCoords[] = { -0.5f, 0.5f, 0.0f, // top left -0.5f, -0.5f, 0.0f, // bottom left 0.5f, -0.5f, 0.0f, // bottom right 0.5f, 0.5f, 0.0f }; // top right private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices public Square() { // initialize vertex byte buffer for shape coordinates ByteBuffer bb = ByteBuffer.allocateDirect( // (# of coordinate values * 4 bytes per float) squareCoords.length * 4); bb.order(ByteOrder.nativeOrder()); vertexBuffer = bb.asFloatBuffer(); vertexBuffer.put(squareCoords); vertexBuffer.position(0); // initialize byte buffer for the draw list ByteBuffer dlb = ByteBuffer.allocateDirect( // (# of coordinate values * 2 bytes per short) drawOrder.length * 2); dlb.order(ByteOrder.nativeOrder()); drawListBuffer = dlb.asShortBuffer(); drawListBuffer.put(drawOrder); drawListBuffer.position(0); } }
Questo esempio ti offre un'idea di ciò che serve per creare forme più complesse con OpenGL. Nella in generale si usano raccolte di triangoli per disegnare oggetti. Nella prossima lezione imparerai a disegnare queste forme sullo schermo.