我想使用Pygame和OpenGL编写一个复古风格的2D游戏,游戏应该具有低分辨率,例如像DOS中的320x200像素,但窗口大小不应该改变。
我将附上图像作为结果的示例。
我尝试在考虑缩放的情况下设置投影矩阵,如下所示:
glOrtho(0, 320, 200, 0, -1, 1)
您不需要 PyOpenGL 来完成此任务。您可以使用 Pygame 和
pygame.transform.scale
或 pygame.transform.scale_by
来完成。在 pygame.Surface
上绘制所需大小的所有内容。在应用程序循环结束时,表面会缩放并在窗口中显示 blit
。在以下示例中,display
是缩放后的表面。在循环结束时,它会缩放 16 倍并绘制在窗口中:
import pygame
pygame.init()
window = pygame.display.set_mode((320, 320))
clock = pygame.time.Clock()
scale = 16
display = pygame.Surface((window.get_width() // scale, window.get_height() // scale))
surf = pygame.image.load('sunglasses.png').convert_alpha()
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
display.fill('gray')
display.blit(surf, surf.get_rect(center = display.get_rect().center))
scaled_disaply = pygame.transform.scale_by(display, scale)
window.blit(scaled_disaply, (0, 0))
pygame.display.flip()
pygame.quit()
exit()
glOrtho
是旧版 OpenGL 函数,仅在使用 glBegin
/glEnd
序列或使用固定函数属性进行绘制时才有效。当你想要获得复古风格的纹理时,你需要使用'GL_NEAREST'参数设置纹理缩小功能和放大功能(参见glTexParameter
)。请注意,所有坐标都必须设置在您用 glOrtho
指定的空间中。请参阅以下基本示例:
import pygame
from OpenGL.GL import *
def surfaceToTexture(pygame_surface):
texture_oj = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texture_oj)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
rgba_surface = pygame.image.tostring(pygame_surface, 'RGBA')
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, *pygame_surface.get_size(), 0, GL_RGBA, GL_UNSIGNED_BYTE, rgba_surface)
glBindTexture(GL_TEXTURE_2D, 0)
return texture_oj
def drawTextrue(texture_obj, rect):
glEnable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, texture_obj)
glBegin(GL_QUADS)
glTexCoord2f(0, 0); glVertex2f(rect.left, rect.bottom)
glTexCoord2f(0, 1); glVertex2f(rect.left, rect.top)
glTexCoord2f(1, 1); glVertex2f(rect.right, rect.top)
glTexCoord2f(1, 0); glVertex2f(rect.right, rect.bottom)
glEnd()
glDisable(GL_TEXTURE_2D)
pygame.init()
window = pygame.display.set_mode((320, 320), pygame.OPENGL | pygame.DOUBLEBUF | pygame.OPENGLBLIT)
clock = pygame.time.Clock()
surf = pygame.image.load('sunglasses.png').convert_alpha()
surf_rect = surf.get_rect()
surf_tecture = surfaceToTexture(surf)
scale = 16
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
width = window.get_width() // scale
height = window.get_height() // scale
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0, width, 0, height, -1, 1)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glClearColor(0.5, 0.5, 0.5, 1)
glClear(GL_COLOR_BUFFER_BIT)
glDisable(GL_DEPTH_TEST)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
surf_rect.center = (width // 2, height // 2)
drawTextrue(surf_tecture, surf_rect)
pygame.display.flip()
clock.tick(100)
pygame.quit()
exit()