2011-07-05 21 views
10

Tôi cứ chạm vấn đề này khi xây dựng game engine nơi lớp học của tôi muốn giống như thế này:OO kiến ​​trúc cho rendering trong các trò chơi dựa shader

interface Entity { 
    draw(); 
} 

class World { 
    draw() { 
    for (e in entities) 
     e.draw(); 
    } 
} 

Đó chỉ là giả mã để hiển thị khoảng cách vẽ xảy ra. Mỗi lớp con thực thể thực hiện bản vẽ của riêng nó. Thế giới vòng qua tất cả các thực thể không theo thứ tự cụ thể và yêu cầu họ tự vẽ từng cái một.

Nhưng với đồ họa dựa trên bóng đổ, điều này có xu hướng cực kỳ kém hiệu quả hoặc thậm chí không khả thi. Mỗi loại thực thể có lẽ sẽ có chương trình đổ bóng riêng. Để giảm thiểu thay đổi chương trình, tất cả các thực thể của từng loại cụ thể cần phải được vẽ cùng nhau. Các loại thực thể đơn giản, như các hạt, cũng có thể muốn tổng hợp bản vẽ của chúng theo những cách khác, như chia sẻ một mảng đỉnh lớn. Và nó thực sự là lông với pha trộn và như vậy, nơi một số loại thực thể cần phải được trả lại tại những thời điểm nhất định liên quan đến những người khác, hoặc thậm chí nhiều lần cho các đường chuyền khác nhau.

Điều tôi thường kết thúc là một số loại trình kết xuất đồ họa cho mỗi lớp thực thể giữ một danh sách tất cả các phiên bản và rút tất cả chúng cùng một lúc. Điều đó không quá tệ vì nó tách bản vẽ khỏi logic trò chơi. Nhưng trình kết xuất cần tìm ra tập hợp con của các thực thể cần vẽ và nó cần truy cập vào nhiều phần khác nhau của đường ống đồ họa. Đây là nơi mà mô hình đối tượng của tôi có xu hướng lộn xộn, với nhiều mã trùng lặp, khớp nối chặt chẽ và những thứ xấu khác.

Vì vậy, câu hỏi của tôi là: kiến ​​trúc tốt cho loại bản vẽ trò chơi nào hiệu quả, linh hoạt và mô-đun?

+0

Thực tế là bạn đang tách nó khỏi mọi thứ khác là tốt để bắt đầu với, và nó có vẻ như lộn xộn của nó bởi vì ... của nó ... _messy_. ** Cần thiết ** lộn xộn là không may, nhưng vẫn còn cần thiết. Nhưng tôi nghi ngờ bạn sẽ xem đây là một câu trả lời… –

Trả lời

1

Đây không phải là câu hỏi dễ trả lời, vì có nhiều cách để giải quyết vấn đề. Một ý tưởng hay là xem xét một số công cụ Game/Rendering và xem cách điều này được xử lý ở đó. Một điểm khởi đầu tốt sẽ là Ogre, kể từ khi nguồn tài liệu và nguồn mở của nó tốt.

Theo như tôi biết, nó tách dữ liệu đỉnh khỏi các thành phần vật liệu (shaders) thông qua các tập lệnh vật liệu dựng sẵn. Trình kết xuất tự biết lưới sẽ được vẽ theo thứ tự nào và với bóng đổ nào (và đường đi của nó).

Tôi biết câu trả lời này hơi mơ hồ, nhưng tôi hy vọng tôi có thể cung cấp cho bạn một gợi ý hữu ích.

8

Sử dụng cách tiếp cận hai giai đoạn: Vòng lặp đầu tiên thông qua tất cả các thực thể, nhưng thay vì vẽ, hãy để chúng chèn tham chiếu vào chính chúng vào danh sách lô (bản vẽ). Sau đó, sắp xếp danh sách theo trạng thái OpenGL và sử dụng shader; sau khi sắp xếp các đối tượng thay đổi trạng thái chèn tại mọi trạng thái transistion.

Cuối cùng lặp qua danh sách thực hiện thường trình vẽ của từng đối tượng được tham chiếu trong danh sách.

+0

nếu bạn có động cơ khác nhau thì sao? OpenGL, DirectX? – GorillaApe

+0

@Parhs: Cả OpenGL lẫn DirectX đều không phải là động cơ. Chúng là các API. Và giai đoạn đầu tiên này được gọi là "thiết lập khung" thường được thực hiện trong các bộ phận bằng mã trình kết xuất nói đến API và một phần bằng mã quản lý cảnh. Ví dụ như culling culling là một cái gì đó mã cảnh là phù hợp hơn cho, kết cấu và nhà nước shader nên được sắp xếp theo các mã renderer. Ngoài ra, bạn không phải làm mọi thứ trong một lần. Nó hoàn toàn tốt đẹp để đi qua đầu tiên (trong mã cảnh) trên tất cả các hộp giới hạn để tiêu hủy và phân loại theo chiều sâu. Sau đó, đưa danh sách này đến trình kết xuất để tinh chỉnh thêm. – datenwolf

+0

Cảm ơn bạn đã trả lời. Tuy nhiên vấn đề của tôi là ở đây.Bạn nói "thực hiện thường trình vẽ của từng đối tượng". Điều gì sẽ xảy ra nếu bạn muốn sử dụng nhiều API (direct2d, opengl etc)? Tôi có nghĩa là vẽ() trong mỗi đối tượng nên có thực hiện cho tất cả api? Hoặc renderer cũng quan tâm đến việc vẽ? – GorillaApe

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