2012-04-24 17 views
8

Pracuję nad grafiką 2D OpenGL z grafiką sprite. Niedawno poinformowano mnie, że powinienem używać wywołań OpenGL ES, ponieważ jest to podzbiór OpenGL i pozwoli mi łatwiej przenosić go na platformy mobilne. Większość kodu jest po prostu wzywa do funkcji draw_image, który jest zdefiniowany tak:Jak ponownie napisać aplikację 2D OpenGL dla 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(); 
} 

Co muszę zmienić, aby ta OpenGL ES kompatybilne? Powodem, dla którego używam funkcji stałej zamiast shaderów jest to, że rozwijam się na maszynie, która nie obsługuje GLSL.

+0

Która wersja GL ES? –

+0

1.1 Przypuszczam, że używam stałego rurociągu. – Skyler

Odpowiedz

13

W OpenGL ES 1.1 można użyć funkcji glVertexPointer(), glColorPointer(),i glDrawArrays() do narysowania kwadratu. W przeciwieństwie do implementacji OpenGL, będziesz musiał opisać struktury (wektory, kolory, współrzędne tekstury), z których zbudowany jest twój quad, zamiast tylko korzystać z wbudowanych metod.

Oto przykład kodu, który powinien zrobić, co chcesz. (Użyłem nazw argumentów używanych w definicji funkcji, więc powinno być proste przeniesienie kodu z przykładu.)

Najpierw należy zdefiniować strukturę jednego wierzchołka kwadratu. Spowoduje to zachowanie czterech pozycji wierzchołków, kolorów i współrzędnych tekstury.

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

Następnie należy określić strukturę opisującą cały quad składający się z czterech wierzchołków:

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

Teraz instancji swój quad i przypisać quad informacji wierzchołków (pozycje, kolory, współrzędne tekstury):

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

Teraz powiedz OpenGL, jak narysować quad. Połączenia do gl...Pointer zapewniają OpenGL z odpowiednimi przesunięciami i rozmiarami do wartości struktury wierzchołków, dzięki czemu mogą później wykorzystać te informacje do rysowania kwadratu.

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

Wreszcie przypisz teksturę i narysuj kwadrat. glDrawArrays mówi OpenGL, aby użyć wcześniej zdefiniowanych przesunięć wraz z wartościami zawartymi w obiekcie Quad, aby narysować kształt zdefiniowany przez wierzchołki 4.

glBindTexture(GL_TEXTURE_2D, tex); 

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

glBindTexture(GL_TEXTURE_2D, 0); 

Należy również pamiętać, że korzystanie z OpenGL ES 1 jest całkowicie OK, jeśli nie potrzebujesz shaderów. Główną różnicą między ES1 i ES2 jest to, że w ES2 nie ma ustalonego potoku, więc musisz sam wdrożyć stos matryc i shaderów dla podstawowego renderowania. Jeśli nie masz nic przeciwko funkcjonalności oferowanej przez stacjonarny potok, użyj OpenGL ES 1.

+0

Dobrze, ale nie do końca rozumiem, jak mogę to przetłumaczyć na funkcję. Skąd pochodzą rzeczy takie jak Vec2 - otrzymuję komunikat "Vec2 nie określa typu" podczas próby skompilowania go. – Skyler

+0

Z jego przykładu: "(rozważ Vec2 jako strukturę dwóch zmiennych (x, y) i koloru struct z 4 bajtami (r, g, b, a))" –

+0

Właśnie zredagowałem swoją odpowiedź, mam nadzieję, że jest bardziej przydatne dla ciebie teraz. Powinno być względnie proste użycie tego jako szablonu dla twojego portu. – starbugs