2012-04-24 16 views
8

Sto lavorando a un gioco OpenGL 2D con grafica sprite. Recentemente mi è stato consigliato di utilizzare le chiamate OpenGL ES in quanto è un sottoinsieme di OpenGL e mi consentirebbe di portarlo più facilmente su piattaforme mobili. La maggior parte del codice è solo chiama a una funzione draw_image, che è definita in modo da:Come riscrivere l'app OpenGL 2D per OpenGL ES?

void draw_img(float x, float y, float w, float h, GLuint tex,float r=1,float g=1, float b=1) { 
    glColor3f(r,g,b); 
    glEnable(GL_TEXTURE_2D); 
    glBindTexture(GL_TEXTURE_2D, tex); 
    glBegin(GL_QUADS); 
     glTexCoord2f(0.0f, 0.0f); 
     glVertex2f(x, y); 
     glTexCoord2f(1.0f, 0.0f); 
     glVertex2f(w+x, y); 
     glTexCoord2f(1.0f, 1.0f); 
     glVertex2f(w+x, h+y); 
     glTexCoord2f(0.0f, 1.0f); 
     glVertex2f(x, h+y); 
    glEnd(); 
} 

Di cosa ho bisogno di cambiare per rendere questo OpenGL ES compatibili? Inoltre, il motivo per cui sto usando una funzione fissa piuttosto che uno shader è che sto sviluppando su una macchina che non supporta GLSL.

+0

Quale versione di GL ES? –

+0

1.1 Suppongo, mentre sto usando la pipeline fissa. – Skyler

risposta

13

In OpenGL ES 1.1 Uso delle funzioni glVertexPointer(), glColorPointer(), glTexCoordPointer() e glDrawArrays() per disegnare un quad. In contrasto con l'implementazione di OpenGL, dovrai descrivere le strutture (vettori, colori, coordinate della trama) del tuo quad invece di usare solo i metodi integrati glTexCoord2f, glVertex2f e glColor3f.

Ecco alcuni esempi di codice che dovrebbero fare ciò che si desidera. (Ho usato i nomi degli argomenti utilizzati nella definizione della funzione, quindi dovrebbe essere semplice per portare il codice dell'esempio.)

Innanzitutto, è necessario definire una struttura per un vertice del quad. Ciò manterrà le posizioni quad-vertice, i colori e le coordinate della trama.

// Define a simple 2D vector 
typedef struct Vec2 { 
    float x,y; 
} Vec2; 

// Define a simple 4-byte color 
typedef struct Color4B { 
    GLbyte r,g,b,a; 
}; 

// Define a suitable quad vertex with a color and tex coords. 
typedef struct QuadVertex { 
    Vec2 vect;    // 8 bytes 
    Color4B color;   // 4 bytes 
    Vec2 texCoords;   // 8 bytes 
} QuadVertex; 

Quindi, è necessario definire una struttura che descrive l'intero quad composto da quattro vertici:

// Define a quad structure 
typedef struct Quad { 
    QuadVertex tl; 
    QuadVertex bl; 
    QuadVertex tr; 
    QuadVertex br; 
} Quad; 

Ora, istanziare tuo quad e assegnare quad informazioni vertice (posizioni, i colori, le coordinate della texture):

Quad quad; 
quad.bl.vect = (Vec2){x,y}; 
quad.br.vect = (Vec2){w+x,y}; 
quad.tr.vect = (Vec2){w+x,h+y}; 
quad.tl.vect = (Vec2){x,h+y}; 
quad.tl.color = quad.tr.color = quad.bl.color = quad.br.color 
       = (Color4B){r,g,b,255}; 
quad.tl.texCoords = (Vec2){0,0}; 
quad.tr.texCoords = (Vec2){1,0}; 
quad.br.texCoords = (Vec2){1,1}; 
quad.bl.texCoords = (Vec2){0,1}; 

Ora dire a OpenGL come disegnare il quad. Le chiamate a gl...Pointer forniscono a OpenGL le correzioni e le dimensioni giuste ai valori della struttura del vertice, in modo che possa successivamente utilizzare tali informazioni per disegnare il quad.

// "Explain" the quad structure to OpenGL ES 

#define kQuadSize sizeof(quad.bl)  
long offset = (long)&quad; 

// vertex 
int diff = offsetof(QuadVertex, vect); 
glVertexPointer(2, GL_FLOAT, kQuadSize, (void*)(offset + diff)); 

// color 
diff = offsetof(QuadVertex, color); 
glColorPointer(4, GL_UNSIGNED_BYTE, kQuadSize, (void*)(offset + diff)); 

// texCoods 
diff = offsetof(QuadVertex, texCoords); 
glTexCoordPointer(2, GL_FLOAT, kQuadSize, (void*)(offset + diff)); 

Infine, assegnare la trama e disegnare il quad. glDrawArrays indica a OpenGL di utilizzare gli offset precedentemente definiti insieme ai valori contenuti nell'oggetto Quad per disegnare la forma definita dai vertici 4.

glBindTexture(GL_TEXTURE_2D, tex); 

// Draw the quad 
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

glBindTexture(GL_TEXTURE_2D, 0); 

Si noti inoltre che è perfettamente OK utilizzare OpenGL ES 1 se non sono necessari shader. La principale differenza tra ES1 ed ES2 è che, in ES2, non esiste una pipeline fissa, quindi è necessario implementare uno stack matrix più shader per il rendering di base da soli. Se stai bene con la funzionalità offerta dalla pipeline fissa, usa semplicemente OpenGL ES 1.

+0

Ok, ma non capisco perfettamente come posso tradurre questo in una funzione. Da dove vengono le cose come Vec2 - Ottengo 'Vec2 non nomina un tipo' quando cerco di compilarlo. – Skyler

+0

Dal suo esempio: "(considera Vec2 come una struttura di due float (x, y) e colora una struct con 4 byte (r, g, b, a))" –

+0

Ho appena modificato la mia risposta, spero che sia più utile per te ora. Dovrebbe essere relativamente semplice usare questo come modello per la tua porta ora. – starbugs