Zachary Milner
Zachary Milner

Reputation: 333

How can I draw using pygame, while also drawing with pyopengl?

I have a program that is written in python and uses pygame along with pyopengl. The only problem is, I can't draw anything on the screen with pygame.draw which is what I was going to use for interfacing with my program. I would like to know if there is a way to draw using pygame's system while also drawing 3D using pyopengl behind it.

Upvotes: 5

Views: 1560

Answers (1)

Rabbid76
Rabbid76

Reputation: 210968

You can't do that directly.

However you can draw on a pygame.Surface object with the pygame.draw module or pygame.Surface.blit. Use pygame.PixelArray to access the pixels on the surface directly. Use the pixels to generate an OpenGL Texture object. This texture can be used in 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)

In the other direction you can render into a OpenGL Renderbuffer or Texture object (see Framebuffers). Load the texture from the GPU with glReadPixels or glGetTexImage and create a pygame.Surface with pygame.image.frombuffer.

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")

See also Does PyGame do 3d?, PyGame and ModernGL library, PyGame and OpenGL 4 or PyGame and OpenGL immediate mode (Legacy OpenGL).

Upvotes: 5

Related Questions