2013-02-22 29 views
6

Hiện đang tạo trò chơi và cố gắng tạo lớp phủ để che màn hình khi nút "menu" được nhấp vào - thứ mà tôi tưởng tượng là khá phổ biến/đơn giản nhưng vẫn gặp sự cố khi triển khai.Sử dụng ShaderProgram trong libgdx để tạo lớp phủ cho menu trong trò chơi

Các thiết lập hiện tại tôi có:

  • TiledMapRenderer: để render TMX gạch (nền/bản đồ)
  • SpriteBatch: đối với tài sản khác nhau (hình ảnh người chơi ví dụ.)
  • Stage: để giữ menu nút
  • ShaderProgram: sử dụng GLSL để tạo hiệu ứng lớp phủ/che
  • SpriteBatch và bản đồ được thiết lập để sử dụng ShaderProgram

Theo đề xuất của nhiều người, để thực hiện, tôi chỉ sử dụng một SpriteBatch - do đó, cùng một lô sprite được sử dụng bởi cả hai nội dung và giai đoạn menu khác nhau.

Mục đích của trình đổ bóng là thêm lớp phủ tối/nửa trong suốt để tô xám màn hình để menu sẽ dễ đọc hơn khi mở.

Vấn đề chính tôi đang gặp là vì tài sản và menu chia sẻ cùng một SpriteBatch, họ cũng chia sẻ shader cùng ... vì vậy, khi tôi cho phép các hiệu ứng đổ bóng mọi thứ (nút nền và menu) là màu xám nhạt.

Làm cách nào tôi chỉ có thể sử dụng một SpriteBatch nhưng chỉ áp dụng Shader cho nền (và giữ các nút menu bình thường/không bị che khuất)?

+0

Một số ý tưởng: Sử dụng một _second_ 'SpriteBatch'?Chỉ áp dụng hiệu ứng chuyển màu xám sau một ngưỡng 'z' nhất định? –

+2

Từ sự hiểu biết của tôi, nó không phải là tốt để sử dụng nhiều hơn một SpriteBatch vì nó có tác động đáng kể đến hiệu suất. Vì vậy, lý do tôi chỉ sử dụng một SpriteBatch. – pyko

Trả lời

9
  • bạn có thể sử dụng: setShader (ShaderProgram shader)

  • bạn có thể thêm một số logic để tạo bóng của bạn để cho phép lớp phủ (đồng phục, đọc một số thuộc tính khác nhau, vv), nhưng điều này không được khuyến khích bởi vì mỗi dòng bạn đặt ở đó được thực thi hàng nghìn lần mỗi giây.

  • [Được khuyến nghị] bạn thực sự có thể vẽ lớp phủ thực. Có một kết cấu nhỏ màu xám (8x8px) với độ trong suốt và vẽ nó sau nền sau và trước menu. Đó sẽ là tọa độ màn hình, giống như menu, phải không? vì vậy nó sẽ không thêm bất kỳ sự phức tạp nào (hoặc tạo ra một sprite đủ lớn).

  • [Nâng cao] cung cấp trò chơi của bạn tạm dừng khi bạn nhấn menu, bạn có thể sao chép màn hình của mình sang FBO khi nút menu được nhấp. Sau đó, bạn có thể xử lý hình ảnh (làm tối, làm mờ) và sử dụng làm hình nền cho menu. Điều đó sẽ cho phép hiệu ứng đẹp hơn, và sẽ thực sự hiệu quả hơn, vì bản vẽ cảnh lỗ được "lưu trữ" bên trong fbo (nhanh hơn để vẽ một kết cấu fbo đơn lẻ, hơn là tính toán lại cảnh lỗ).

+0

Tò mò, tại sao bạn khuyên bạn nên vẽ một lớp phủ thực tế? Nhiều người biểu diễn hơn? hoặc bởi vì nó đơn giản hơn. (Lớp phủ có thể sẽ bao phủ toàn bộ màn hình). Không bao giờ sử dụng FBO trước, sẽ nhìn vào chúng :) – pyko

+1

Lý do 1 là nó hoàn toàn tách rời khỏi trò chơi (nền) của bạn. Ý tôi là, khi menu không được hiển thị, nó sẽ không thêm bất kỳ tác động hiệu suất nào. Nếu bạn sử dụng một "shadable" shader, những "if" s bạn thêm được thực hiện mỗi đỉnh, mỗi khung. Bạn nên tối ưu hóa việc kết xuất trò chơi mà chắc chắn sẽ là nút cổ chai của bạn và việc tách riêng menu của bạn là một tối ưu hóa. Lý do 2- Có, Đơn giản hơn, bạn không cần phải tối ưu hóa nhiều menu (vì không phải là nút cổ chai), vì vậy bạn càng thêm phức tạp, thì tốt hơn.// (FBO sẽ giống như ảnh chụp màn hình trong trường hợp của bạn) –

+0

Cảm ơn vì sự trả lời! Đó là những gì tôi đã tìm thấy - việc thực hiện shader có hiệu suất tồi tệ hơn so với lớp phủ hình ảnh. Sẽ xem xét FBO cho các hiệu ứng nâng cao :) – pyko

2

Sau khi hỏi xung quanh trên các diễn đàn libgdx, figured it out - giải pháp là để thiết lập sức mạnh trong shader, sau đó tuôn lô (tức spriteBatch.flush().) Trước khi vẽ tiếp theo điều.

Vì vậy, khoảng ...

spriteBatch.start(); 
//draw stuff 
spriteBatch.flush(); 
// set shader strength/variables 
// draw more stuff (is now affected by shader) 
spriteBatch.end(); 
Các vấn đề liên quan