Làm cách nào để thay đổi kích thước pixel art trong Pyglet mà không làm mờ nó?


7

Tôi có một khối hình ảnh 8 x 8 pixel và tôi muốn thay đổi kích thước chúng trong trò chơi của mình để chúng tăng gấp đôi (16x16 pixel, ví dụ: biến mỗi pixel thành một khối 2x2.) Điều tôi đang cố gắng đạt được là một Minecraft- như hiệu ứng, trong đó bạn có tỷ lệ hình ảnh pixel nhỏ đến các pixel khối lớn hơn.

Trong Pyglet, thuộc tính của sprite scalelàm mờ các pixel. Có cách nào khác không?

Mã làm việc:

Đây là giải pháp hiệu quả (nhờ sự kiên trì của DMan và sự sáng suốt của Jimmy):

image = resource.image('tileset.png')                                                                                                                                                               
texture = image.get_texture()   
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST)                                                                                                                               
texture.width = 16 # resize from 8x8 to 16x16                                                                                                                                                                  
texture.height = 16                                                                                                                                                                                                                                                                                                                       
texture.blit(100, 30) # draw                                                                                                                                                                        

3
Tôi không quen thuộc với Pyglet đủ để đưa ra câu trả lời này, nhưng tôi thấy rằng bạn có thể sử dụng OpenGL, vì vậy from pyglet.gl import *, sau đó thực hiện cuộc gọi tới Talisman.org/opengl-1.1/Reference/glTexParameter.html với GL_NEAREST.
DMan

Cảm ơn, tôi sẽ xem xét điều đó, nhưng tôi chưa bao giờ sử dụng OpenGL trước đây. Loại mới đối với lập trình đồ họa: \
theabraham

Tôi không biết Pyglet làm được bao nhiêu đằng sau hậu trường, nhưng một cái gì đó như thế này có thể hoạt động : glEnable(GL_TEXTURE_2D). Sau đó, hãy nói rằng bạn đã có một cuộc gọi đến a = image.load('blah.jpg'). Chỉ định tex = a.texturesau đó glBindTexture(GL_TEXTURE_2D, texture.id)và cuối cùng là một cuộc gọi đến pyglet.gl.glTexParameteri(pyglet.gl.GL_TEXTURE_2D, pyglet.gl.GL_TEXTURE_MIN_FILTER, pyglet.gl.GL_NEAREST). Tôi không quá quen thuộc với không gian tên cho OpenGL trong python, vì vậy tôi đã để lại toàn bộ cuộc gọi đủ điều kiện. Kể từ khi chúng tôi nhập khẩu OpenGL, tôi tin rằng bạn có thể loại bỏ ít nhất các pyglet ở phía trước, và có lẽ GL quá.
DMan

Này, tôi đã thử nó mà không thành công, bạn có thể kiểm tra lại mã của tôi trong bản cập nhật không? Ngoài ra, bạn có tài nguyên tốt nào để giúp tôi hiểu các lệnh GL này không? Tôi đánh giá cao sự giúp đỡ.
theabraham

Một điều tôi nhận thấy ngay lập tức là bạn đặt chiều rộng và chiều cao kết cấu trước khi gọi đến glTexParameteri. OpenGL 1/2 / ~ 3 mà tôi đoán Pyglet dựa trên việc có các lệnh chế độ tức thời này . Đó là, bạn thực thi một lệnh để thay đổi trạng thái, sau đó mọi thứ sau đó sẽ thay đổi. Tôi sẽ bắt đầu bằng cách di chuyển các cuộc gọi bên dưới các cuộc gọi gl.
DMan

Câu trả lời:


8

Theo yêu cầu của người bình luận ...

Cảnh báo cho các chuyên gia Pyglet: Có thể có một cách Pyglet tuyệt vời để làm điều này, và đây không phải là nó. Đó là một cách OpenGL tuyệt vời. Bạn đã được cảnh báo!

Bạn có thể làm điều này trong OpenGL bằng cách trước tiên ràng buộc kết cấu, sau đó gọi glTexParameterihoặc các biến tương tự. Bạn có thể làm điều này trong Pyglet bằng cách nhập OpenGL:

from pyglet.gl import *

Sau đó, bạn có thể kích hoạt GL_TEXTURE_2Dđể đặt mục tiêu. Điều này không phải lúc nào cũng cần thiết, nhưng tôi đang giữ điều này hoàn chỉnh cho một số ràng buộc khác.

glEnable(GL_TEXTURE_2D)

Trong Pyglet, có vẻ như bạn cũng không phải liên kết kết cấu. Đôi khi bạn phải tải hình ảnh của mình, lấy id kết cấu, sau đó sử dụng glBindTexture(GL_TEXTURE_2D, texture.id). Giả định của tôi rằng đây đã là trạng thái được đặt cho bạn trong Pyglet.

Bước tiếp theo là gọi glTexParameteri. Cảm ơn Jimmy đã sửa lỗi cho tôi về điều này: cuộc gọi chính xác là:

gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST)

Phân tích nhanh: đầu tiên chỉ là đặt mục tiêu để OpenGL biết bạn đang nói về điều gì, sau đó tham số thứ hai là loại bộ lọc bạn muốn đặt. MAG_FILTERlà chính xác bởi vì nó kiểm soát độ phóng đại của kết cấu. Tham số cuối cùng là GL_NEAREST, điều khiển cách kết cấu được chia tỷ lệ. GL_NEARESTvề cơ bản là một thang đo nhanh mang lại kết cấu theo kiểu pixel. GL_LINEARlà bình thường và thay vào đó sẽ làm mờ kết cấu của bạn.

Phiên bản OpenGL này tôi đang nói đến (về <OpenGL 3.2 chính thức) sử dụng chế độ ngay lập tức, thiết lập trạng thái. Bây giờ trạng thái được thiết lập, bạn có thể chia tỷ lệ kết cấu của bạn. Tôi không thể thấy tốt hơn là hiển thị mã mà Renold đã đăng dưới dạng mã làm việc.

image = resource.image('tileset.png')                                                                                                                                                               
texture = image.get_texture()   
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST)                                                                                                                               
texture.width = 16 # resize from 8x8 to 16x16                                                                                                                                                                  
texture.height = 16                                                                                                                                                                                                                                                                                                                       
texture.blit(100, 30) # draw

Renold, nếu bạn có thể xem cái này và đề xuất cải tiến, điều đó thật tuyệt. Tôi quan tâm đến một cái gì đó mặc dù. Nếu bạn loại bỏ texture = image.get_texture(), nó có hoạt động không? Có vẻ như bạn không bao giờ gọi nó, trừ khi điều đó ràng buộc kết cấu bên trong.
DMan

Vâng, hóa ra bạn không cần nó. Cuối cùng tôi chỉ cần đặt hình ảnh vào một sprite, và nó hoạt động tốt: image = resource.image('tileset.png') \n sprite = sprite.Sprite(image, x_pos, y_pos) \n sprite.scale = 2 \n
theabraham

4

Đối với những người như tôi, những người chỉ đơn giản là tạo ra một trò chơi theo phong cách retro, nơi họ muốn MỌI THỨ được chia tỷ lệ thành pixel, câu trả lời nhanh đơn giản là bắt đầu mã của bạn bằng:

from pyglet.gl import *
glEnable(GL_TEXTURE_2D)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)

Sau đó, tất cả việc sử dụng các họa tiết của bạn, vv từ đó trở đi vẫn đẹp và pixelated.

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.