2012-04-24 58 views
8

Tôi đang làm việc trên một trò chơi OpenGL 2D với đồ họa sprite. Gần đây tôi đã khuyên rằng tôi nên sử dụng các cuộc gọi OpenGL ES vì nó là một tập con của OpenGL và sẽ cho phép tôi chuyển nó dễ dàng hơn đến các nền tảng di động. Phần lớn mã chỉ là các lệnh gọi hàm draw_image, được xác định như vậy:Cách viết lại ứng dụng OpenGL 2D cho 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(); 
} 

Tôi cần thay đổi gì để tương thích với OpenGL ES này? Ngoài ra, lý do tôi đang sử dụng chức năng cố định thay vì shaders là tôi đang phát triển trên một máy không hỗ trợ GLSL.

+0

Phiên bản GL ES nào? –

+0

1.1 Tôi cho rằng, khi tôi đang sử dụng đường ống cố định. – Skyler

Trả lời

13

Trong OpenGL ES 1.1, hãy sử dụng các chức năng glVertexPointer(), glColorPointer(), glTexCoordPointer()glDrawArrays() để vẽ hình tam giác. Ngược lại với việc triển khai OpenGL của bạn, bạn sẽ phải mô tả các cấu trúc (vec-tơ, màu sắc, tọa độ kết cấu) mà quad của bạn bao gồm thay vì chỉ sử dụng các phương pháp được xây dựng trong glTexCoord2f, glVertex2fglColor3f.

Dưới đây là một số mã ví dụ nên làm những gì bạn muốn. (Tôi đã sử dụng các tên đối số mà bạn đã sử dụng trong định nghĩa hàm của mình, vì vậy sẽ đơn giản để chuyển mã của bạn từ ví dụ.)

Trước tiên, bạn cần xác định cấu trúc cho một đỉnh của quad của bạn. Điều này sẽ giữ các vị trí đỉnh tứ, màu sắc và tọa độ kết cấu.

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

Sau đó, bạn cần xác định một cấu trúc mô tả toàn bộ quad gồm bốn đỉnh:

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

Bây giờ, nhanh chóng quad của bạn và gán thông tin đỉnh quad (vị trí, màu sắc, kết cấu tọa độ):

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

Bây giờ, hãy cho OpenGL biết cách vẽ hình tứ giác. Các cuộc gọi đến gl...Pointer cung cấp OpenGL với các offset và kích thước phù hợp với các giá trị của cấu trúc đỉnh của bạn, vì vậy sau này nó có thể sử dụng thông tin đó để vẽ 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)); 

Cuối cùng, chỉ định họa tiết và vẽ hình tam giác. glDrawArrays yêu cầu OpenGL sử dụng các offset được xác định trước đó cùng với các giá trị chứa trong đối tượng Quad của bạn để vẽ hình dạng được xác định bởi 4 đỉnh.

glBindTexture(GL_TEXTURE_2D, tex); 

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

glBindTexture(GL_TEXTURE_2D, 0); 

Cũng xin lưu ý rằng bạn hoàn toàn có thể sử dụng OpenGL ES 1 nếu bạn không cần trình đổ bóng. Sự khác biệt chính giữa ES1 và ES2 là, trong ES2, không có đường ống cố định, vì vậy bạn sẽ cần phải triển khai một ngăn xếp ma trận cộng với các trình tạo bóng cho bản dựng cơ bản của riêng bạn. Nếu bạn ổn với chức năng được cung cấp bởi đường ống cố định, chỉ cần sử dụng OpenGL ES 1.

+0

Ok, nhưng tôi không hoàn toàn hiểu làm thế nào tôi có thể dịch này thành một chức năng. Những thứ như Vec2 đến từ đâu - tôi nhận được 'Vec2 không đặt tên một loại' khi cố gắng biên dịch nó. – Skyler

+0

Từ ví dụ của mình: "(xem xét Vec2 là cấu trúc của hai phao (x, y) và tô màu một cấu trúc với 4 byte (r, g, b, a))" –

+0

Tôi vừa chỉnh sửa câu trả lời của mình, hy vọng nó là hữu ích hơn cho bạn bây giờ. Nó sẽ được tương đối đơn giản để sử dụng điều này như là một mẫu cho cổng của bạn bây giờ. – starbugs

Các vấn đề liên quan