2012-04-24 7 views
8

Estoy trabajando en un juego OpenGL 2D con gráficos de sprite. Hace poco me avisaron que debería usar las llamadas de OpenGL ES, ya que es un subconjunto de OpenGL y me permitiría transferirlo más fácilmente a las plataformas móviles. La mayor parte del código es sólo llama a una función draw_image, que se define así:¿Cómo volver a escribir la aplicación 2D OpenGL para 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(); 
} 

¿Qué necesito cambiar para hacer ES compatible con OpenGL esto? Además, la razón por la que estoy usando funciones fijas en lugar de sombreadores es que estoy desarrollando en una máquina que no es compatible con GLSL.

+0

¿Qué versión de GL ES? –

+0

1.1 Supongo, ya que estoy usando la tubería fija. – Skyler

Respuesta

13

En OpenGL ES 1.1 uso las funciones glVertexPointer(), glColorPointer(), glTexCoordPointer() y glDrawArrays() para dibujar un quad. A diferencia de su implementación de OpenGL, tendrá que describir las estructuras (vectores, colores, coordenadas de textura) en las que consiste su quad en lugar de simplemente usar los métodos integrados glTexCoord2f, glVertex2f y glColor3f.

Aquí hay un código de ejemplo que debe hacer lo que desee. (He utilizado los nombres de los argumentos que usó en la definición de su función, por lo que debería ser simple portar su código desde el ejemplo.)

Primero, necesita definir una estructura para un vértice de su quad. Esto mantendrá las posiciones de los vértices cuádruples, los colores y las coordenadas de la textura.

// 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; 

Entonces, usted debe definir una estructura que describe todo el quad que consiste en cuatro vértices:

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

Ahora, una instancia de tu quad y asignar información vértice quad (posiciones, colores, coordenadas de textura):

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}; 

Ahora dígale a OpenGL cómo dibujar el quad. Las llamadas al gl...Pointer proporcionan OpenGL con los desplazamientos y tamaños correctos a los valores de su estructura de vértices, por lo que luego puede usar esa información para dibujar el cuadrángulo.

// "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)); 

Finalmente, asigne la textura y dibuje el cuadrángulo. glDrawArrays le dice a OpenGL que use los desplazamientos previamente definidos junto con los valores contenidos en su objeto Quad para dibujar la forma definida por los vértices 4.

glBindTexture(GL_TEXTURE_2D, tex); 

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

glBindTexture(GL_TEXTURE_2D, 0); 

Tenga en cuenta también que está perfectamente bien utilizar OpenGL ES 1 si no necesita sombreadores. La principal diferencia entre ES1 y ES2 es que, en ES2, no hay una tubería fija, por lo que necesitaría implementar una matriz de matriz más sombreadores para la representación básica por su cuenta. Si está de acuerdo con la funcionalidad ofrecida por la tubería fija, solo use OpenGL ES 1.

+0

Ok, pero no entiendo completamente cómo puedo traducir esto en una función. ¿De dónde vienen cosas como Vec2? Obtengo que 'Vec2 no nombra un tipo' cuando intenta compilarlo. – Skyler

+0

De su ejemplo: "(considere que Vec2 es una estructura de dos flotantes (x, y) y colorea una estructura con 4 bytes (r, g, b, a))" –

+0

Acabo de editar mi respuesta, espero que sea más útil para ti ahora. Debería ser relativamente simple usar esto como una plantilla para su puerto ahora. – starbugs

Cuestiones relacionadas