我如何在使用pygame绘图的同时,还能够使用pyopengl进行绘图?

5
我有一个用Python编写的程序,使用pygame和pyopengl。唯一的问题是,我无法使用pygame.draw在屏幕上绘制任何东西,而这正是我打算用来与我的程序进行交互的工具。我想知道是否有办法在使用pygame系统绘图的同时,在其后面使用pyopengl进行3D绘制。

你不能直接这样做。 - Rabbid76
1个回答

4

你不能直接这样做。

但是,你可以使用pygame.draw模块或pygame.Surface.blitpygame.Surface对象上绘制。使用pygame.PixelArray直接访问表面上的像素。使用像素生成OpenGL 纹理对象。此纹理可用于OpenGL。

def surfaceToTexture(pygame_surface):
    rgba_surface = pygame.image.tostring(pygame_surface, 'RGBA')
    width, height = pygame_surface.get_size()
    texture_obj = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture_obj)
    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)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgba_surface)
    glBindTexture(GL_TEXTURE_2D, 0)
    return texture_obj

image = pygame.image.load('my_image.png')
texture = surfaceToTexture(image)

在另一个方向上,您可以将渲染到OpenGL RenderbufferTexture 对象(请参见Framebuffers)。使用 glReadPixelsglGetTexImage 从GPU加载纹理,并使用 pygame.image.frombuffer 创建 pygame.Surface
size = screen.get_size()
buffer = glReadPixels(0, 0, *size, GL_RGBA, GL_UNSIGNED_BYTE)
pygame.display.flip()
screen_surf = pygame.image.fromstring(buffer, size, "RGBA")

image_buffer = glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE)
image_surf = pygame.image.fromstring(image_buffer, (width, height), "RGBA")

另请参阅PyGame是否支持3D?, PyGame和ModernGL库, PyGame和OpenGL 4PyGame和OpenGL即时模式(Legacy OpenGL)


我不知道如何将像素数组转换为纹理对象。是否有OpenGL函数可以实现? - Zachary Milner
1
@ZacharyMilner 当我看到你的问题时,我以为你熟悉OpenGL。很抱歉,解释OpenGL中所有必要的步骤对于一个单一的Stack Overflow答案来说太过宽泛了。我建议阅读一份好的教程。我最喜欢的是C++的教程(LearnOpenGL)。但也有适用于Python的好教程:Python Opengl - Rabbid76
是的,我对此不太熟悉,因为我通常使用2D工作。我曾经制作过一个相当糟糕的3D渲染器,不过我可能会尝试让它运行起来。 - Zachary Milner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接