Cách nhanh nhất để vẽ quads trong OpenGL ES?


21

Tôi đang sử dụng OpenGL ES 2.0 Tôi có một bó tứ giác được vẽ, rất thích có thể chỉ phải vượt qua 4 đỉnh trên mỗi tứ giác như thể tôi đang sử dụng GL_QUADS, nhưng về cơ bản tôi chỉ muốn biết cách vẽ tốt nhất bó tứ giác riêng biệt.

Cho đến nay những gì tôi đã tìm thấy tôi có thể làm: -GL_TRIANGLES (6 đỉnh trên một quad) -Degenerate GL_TRIANGLE_STRIP (6 đỉnh trên một quad)

Khả năng tôi đã tìm thấy: -GL_TRIANGLE_STRIPS với giá trị chỉ mục đặc biệt đặt lại dải quad (điều này có nghĩa là 5 chỉ mục trên mỗi quad, nhưng tôi không nghĩ rằng điều này là có thể là OpenGL ES 2.0)

Câu trả lời:


33

Chỉ cần sử dụng bộ đệm chỉ mục và GL_TRIANGLES. Trong trường hợp này, bạn cần 4 đỉnh + 6 chỉ số trên mỗi tứ giác (6 chỉ số bổ sung có thể nghe có vẻ lớn nhưng thực tế không phải vậy - một khi bạn đã xây dựng bộ đệm chỉ mục của mình, bạn không phải chạm lại lần nữa). Xem trang này để biết thêm thông tin (tìm kiếm glDrawElements)

Mã ví dụ đơn giản:

GLfloat vertices[] = {-1, -1, 0, // bottom left corner
                      -1,  1, 0, // top left corner
                       1,  1, 0, // top right corner
                       1, -1, 0}; // bottom right corner

GLubyte indices[] = {0,1,2, // first triangle (bottom left - top left - top right)
                     0,2,3}; // second triangle (bottom left - top right - bottom right)

glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);

Ngoài ra, nếu bạn chỉ vẽ một hình tứ giác, bạn chỉ cần 4 đỉnh để vẽ nó bằng các dải tam giác ( như thể hiện trong wikipedia ) nhưng tôi đoán bạn đã biết điều này.


Thủ thuật truyền thống để hợp nhất nhiều dải tam giác thành một dải là "tam giác suy biến": Lặp lại phần tử cuối cùng của một dải và phần tử đầu tiên của dải tiếp theo tạo ra 2 hình tam giác có diện tích bằng 0, do đó không thu được gì. Xem xét các chỉ số quad thứ hai (4, 5, 6, 7). Bộ đệm chỉ mục cho GL_TRIANGLE_STRIP của hai hình có thể là: {0, 1, 2, 3, 3, 4,4, 5, 6, 7}. Các tam giác suy biến là 3,3,43,4,4. Có đáng để làm điều này? Không, trừ khi các hình tứ giác của bạn có xu hướng đi theo cặp (hoặc nhiều hơn) với các cạnh chung. Nếu quad thứ 2 là {3, 2, 4, 5} thì dải là {0,1,3,2,5,4}.
ToolmakerSteve

8
Và để làm rõ điều này với bất kỳ ai đi cùng và cần vẽ một loạt các hình tứ giác: Vì lợi ích của hiệu suất, KHÔNG sao chép mã trên và tạo một glDrawElements gọi ONCE FOR MACHI QUAD . Thay vào đó, xây dựng mảng MỘT đỉnh và MỘT mảng chỉ số bao gồm TẤT CẢ các hình tứ giác bạn muốn vẽ. Sử dụng GL_TRIANGLES, hai hình tứ giác có thể có chỉ số {0,1,2, 0,2,3, 4,5,6, 4,6,7}hoặc tốt như nhau {0,1,2, 2,3,0, 4,5,6, 6,7,4}. Lớp tốt để giúp điều này là glText-Android / SpriteBatch
ToolmakerSteve

6

Sử dụng bộ đệm chỉ mục không nhất thiết phải nhanh hơn, như được chỉ ra trong tài liệu của Apple, "Để có hiệu suất tốt nhất, các mô hình của bạn phải được gửi dưới dạng một dải tam giác đơn không sử dụng bằng glDrawArrays" .

Vì vậy, trong khi a GL_TRIANGLE_STRIPsẽ làm điều đó trong 4 đỉnh mà không cần bộ đệm chỉ mục và bạn có thể sử dụng bộ đệm chỉ mục, thật là khập khiễng khi cố gắng "lưu" lặp lại 2 đỉnh . Vì lý do này, tôi khuyên bạn nên vẽ 2 riêng biệt GL_TRIANGLESvà lặp lại 2 đỉnh trên đường chéo .


8
À, không. Những gì tài liệu nói là các mô hình của bạn được gửi dưới dạng một dải tam giác INDEXED duy nhất. Và câu tiếp theo là, "Để tránh chỉ định dữ liệu cho cùng một đỉnh nhiều lần trong bộ đệm đỉnh, hãy sử dụng bộ đệm chỉ mục riêng và vẽ dải tam giác bằng hàm glDrawElements". Đó chính xác là những gì bạn đã quyết định là 'khập khiễng'.
davidf2281

3
Cho rằng đoạn tài liệu bây giờ đề cập đến glDrawElements chứ không phải glDrawArrays, nó có lẽ đã được viết lại kể từ câu trả lời này. Tuy nhiên, điểm mà tài liệu đưa ra là, về hiệu suất, cung cấp một dải duy nhất (thay vì nhiều dải, do đó nhiều lệnh gọi gl). Trong tình huống này, tôi tin rằng sự khác biệt giữa việc sử dụng các chỉ số hay không là không đáng kể ; điều quan trọng là nhận mọi thứ vào một mảng đỉnh (cộng với một mảng chỉ mục tùy chọn), để bạn có thể thực hiện một cuộc gọi gl.
ToolmakerSteve

0

Lợi ích lớn trên máy tính để bàn là di chuyển dữ liệu vào GL_STATIC_DRAW VBO. Có lẽ điều này cũng đúng trên GPU MBX của iPhone.


-2

Sử dụng GL_TRIANGLE_FANcho một quad sử dụng 4 đỉnh chứ không phải 6.


Đúng, nhưng cũng như vậy GL_TRIANGLE_STRIP, như các câu trả lời khác đã chỉ ra.
Anko

@Ông. Blah - Bạn đã bỏ lỡ điểm của câu hỏi, đó là làm thế nào để thực hiện một cách hiệu quả một loạt các quads. Người ta không nên thực hiện một cuộc gọi gl cho mỗi quad, mà nên kết hợp rất nhiều quads thành một mảng duy nhất, có thể được vẽ bằng một lệnh gọi gl. GL_TRIANGLE_FAN sẽ không giúp với điều này, do đó hiếm khi hữu ích trong kết xuất hiệu suất cao.
ToolmakerSteve
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.