Trong OpenGL, có phải là một ý tưởng tồi khi kết hợp chế độ ngay lập tức và chế độ giữ lại vì lợi ích của GUI không?


8

Giả sử tôi có một cảnh 3D được vẽ glDrawArrays(...)và tôi muốn hiển thị một cái gì đó đơn giản, như lớp phủ 2D. Sẽ là một ý tưởng tồi khi sử dụng chế độ ngay lập tức cho một việc như vậy, thay vì thiết lập trình kết xuất 2D với chế độ giữ lại?

Thí dụ:

void Draw()
{
    // Draw the 3D scene:
    // *does stuff*
    glDrawArrays(...);
    // *some other stuff*

    // Setup a quad with immediate mode (for something like a vignette overlay)
    glBegin(GL_QUADS);
    glTexCoord2f(...); glVertex2f(...);
    glEnd();
}

Minecraft làm điều này. Nó hoạt động tốt, ngoại trừ việc giới hạn phiên bản OpenGL của bạn (đến <3.1 hoặc cấu hình tương thích) và để làm cho GUI của bạn nhanh hơn.
dùng253751

Lưu ý Minecraft cũng có bộ chức năng riêng mô phỏng chế độ tức thời bằng cách sử dụng mảng đỉnh - không khó để viết. Tôi không chắc họ đang sử dụng chúng cho GUI chưa.
dùng253751

Câu trả lời:


7

Đó là một ý tưởng tồi trong chừng mực nó là vô nghĩa. Không có gì để "thiết lập" mà bạn chưa thực hiện, ngoại trừ ma trận chiếu ortho (mà bạn sẽ phải làm trong mọi trường hợp).

Tính di động có lẽ không phải là một vấn đề, mặc dù nó nên được. Các IHV dường như rất miễn cưỡng bỏ hỗ trợ cho chế độ ngay lập tức trong tương lai gần (có vẻ như "hoạt động tốt" ngay cả trong các cấu hình cốt lõi), vì vậy mặc dù chế độ ngay lập tức đã chết từ lâu, nhưng có lẽ nó sẽ tồn tại mãi mãi. Hiệu suất là một câu chuyện khác. Bạn có thực sự muốn thứ gì đó chiếm 0,1% độ phức tạp của cảnh để tiêu tốn 15-20% thời gian của CPU - Cuộc gọi GL tương đối nhẹ, so với ví dụ DX, nhưng chúng không miễn phí - và 15-20% thực thời gian khung do trì hoãn các đường ống dẫn? Bạn thậm chí có thể đủ khả năng đó với ngân sách thời gian của bạn? Hầu hết các trò chơi không thể.

Và dĩ nhiên, những điều kỳ quặc. Ôi những điều kỳ quặc. Vẻ đẹp rõ ràng của chế độ ngay lập tức là nó (dường như) dễ dàng và đơn giản để làm một cái gì đó như vẽ một vài hình tứ giác nhanh chóng. Trong thực tế, chế độ ngay lập tức có thể là một nỗi đau ở phía sau, nó đầy những cạm bẫy không rõ ràng.
Mặt khác, thật dễ dàng (và đơn giản hơn nếu bạn hỏi tôi!) Chỉ cần viết một hàm 5-LỘC nhỏ DrawQuadmà khi được gọi sẽ thêm tọa độ đỉnh và chỉ mục vào bộ nhớ đệm và tăng bộ đếm. Thật ngạc nhiên, sau đó bạn có thể vẽ glDrawArrays/Elementsvà bạn có thể sử dụng lại (bản sao GPU, không chỉ là bản sao người dùng!) Khung tiếp theo miễn là không có gì thay đổi.
Chế độ ngay lập tức phải, không có cách nào khác, phân bổ bộ đệm và thực hiện chuyển PCIe mỗi lần. Hoặc, một cái gì đó tương đương về độ trễ (GPU đọc bộ nhớ chính trên xe buýt, bất cứ điều gì). Người lái xe không thể biết (hoặc giả định) rằng dữ liệu vẫn giống hệt như khung trước đó.

Lấy dữ liệu cho GPU là một hoạt động tốc độ cao, nhưng cũng có độ trễ cao . Không chỉ là việc chuyển nhượng xe buýt cho mỗi gia nhập một phức tạp, giao thức độ trễ cao (vài lớp giao thức, packetizing, lời cảm ơn, vv), nhưng cũng không phải tất cả các GPU thậm chí còn có thể chuyển và rút ra cùng một lúc, hoặc nếu họ có thể làm điều đó , họ có thể không thể chuyển đổi giữa hoặc bắt đầu các hoạt động mới một cách tự do trong khi thực hiện một việc khác. Đọc như: Ngươi không được chuyển nhượng vô ích .


"Không có gì để" thiết lập "mà bạn chưa thực hiện" Kết xuất hàng loạt?
HolyBlackCat

2
Mặc dù các IHV không muốn bỏ chế độ ngay lập tức, nhưng cũng có các trình điều khiển video trong Linux không hỗ trợ phiên bản OpenGL cao hơn trừ khi bạn yêu cầu Cấu hình lõi. Điều này đặc biệt có nghĩa là đồ họa Intel HD ( inteltrình điều khiển), mà cả chip NVidia và AMD khi sử dụng trình điều khiển nguồn mở ( nouveauamdgputương ứng). Tương tự, trên MacOS, bạn cũng không có Hồ sơ tương thích với OpenGL> 2.1.
Ruslan

@HolyBlackCat: Tôi không chắc ý của bạn là gì? OP có một đường ống 3D hoạt động dựa trên glDrawArrays. Vì vậy, có tất cả mọi thứ được thiết lập để thực hiện một cuộc gọi khác glDrawElements(hoặc Array, tùy theo điều kiện nào) để vẽ tất cả các hình tứ giác cho GUI (sau khi viết các đỉnh vào bộ đệm). Các chức năng được tải, bạn có một khung để phân bổ bộ đệm, v.v. Thực sự không có gì đặc biệt để làm cho việc xử lý GUI. Chỉ cần liên kết (hoặc không, nếu bạn có đủ TU còn lại để ràng buộc) kết cấu GUI, đặt ma trận ortho và thực hiện một cuộc gọi rút thăm bổ sung. Làm thế nào để bạn muốn hàng loạt tốt hơn?
Damon

(Tất nhiên tôi đồng ý rằng chế độ ngay lập tức là xấu.) Xin lỗi nếu tôi không rõ ràng. Tôi có nghĩa là quá trình điền vào bộ đệm đỉnh nói. Điều đó thật dễ dàng, nhưng nó sử dụng chế độ ngay lập tức hơn một chút.
HolyBlackCat

12

Cá nhân tôi chỉ thấy nó là xấu vì hai lý do:

  1. Nó rất lỗi thời và không được dùng nữa. Và,
  2. Nó chậm hơn nhiều so với các cách vẽ hiện đại với OpenGL.

Nhưng, nếu nó hoạt động tốt và hiệu suất sẽ không thành vấn đề và nếu bạn không sử dụng các chức năng OpenGL không dùng trong chương trình của mình thì tôi tin bạn có thể làm được. Sẽ chậm hơn khi có TẤN và TẤN GUI, nhưng nếu không phải là nhiều, một lần nữa, hãy tìm nó.

Hiểu điều này, mặc dù. Vào cuối ngày, OpenGL cũng đang làm điều tương tự; vẽ lên màn hình. Chế độ ngay lập tức chỉ chậm hơn nhiều nếu bạn có nhiều thứ đang được xử lý. Vì vậy, bạn nên chọn những gì hữu ích nhất cho nhiệm vụ bạn có trong tâm trí. Hy vọng điều này sẽ giúp bạn ra ngoài!


1

Một nhược điểm khác là nó làm cho mã của bạn ít di động hơn. Một số biến thể OpenGL nhất định không hỗ trợ chế độ ngay lập tức, ví dụ, OpenGL ES. (và khi các thiết bị chạy Android có cỡ nòng lớn hơn như máy tính bảng tăng thêm lực kéo, nó có thể trở nên quan trọng)


0

Sử dụng chế độ ngay lập tức là hoàn toàn không cần thiết cho công việc liên quan đến gui.

Để tạo một mục gui đơn giản, giả sử, một nút:

  1. Bạn cần một lưới tứ giác / tam giác,
  2. Một kết cấu cho lưới
  3. Một biến đổi hình chiếu chính tả

Theo cách này, bạn có thể chỉ cần viết một shader xuyên qua đơn giản mà bỏ qua các cân nhắc về ánh sáng, và bạn chỉ cần chia tỷ lệ của mục gui theo tỷ lệ pixel hoặc một số phần trăm của cửa sổ, sau đó thực hiện thuật toán họa sĩ để kết xuất.

Bằng cách này, bạn có thể thực hiện một hệ thống ui đầy đủ với tất cả các lợi ích hiệu suất của chế độ giữ lại.

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.