How to use Panda3d and Pygame together

1.6k views Asked by At

I am new to game development and am trying to develop a game with panda3d. Can we directly use Pygame modules along with Panda3d ones?

3

There are 3 answers

1
rdb On

Yes. Both Panda3D and PyGame are Python modules that can be used in any (compatible) Python installation. There is (at least to my awareness) nothing about either library that prevents you from importing other Python modules.

Depending on what you're trying to do, though, the answer may be more tricky. For instance, presumably both PyGame and Panda3D have their own main game loops, and using them together would require making one game loop run as a part of the other library's game loop.

Sharing resources or graphics contexts would also be tricky, as both libraries manage their own graphics state. It would be a lot more tricky (but not necessarily impossible) if your question included, for example, drawing PyGame elements into a Panda3D window or vice versa.

0
AzlanCoding On

I have been experimenting with using Panda3D in Pygame. The following is a working code that displays the built-in 3D RGB Cube that is rotating using Panda3D. The Panda3D Processes the 3D Images in an offscreen buffer. It will then use Pillow to convert the Image from Panda3D into a Pygame Displayable.

from PIL.Image import frombytes, merge
import pygame
from direct.showbase.ShowBase import ShowBase
from panda3d.core import Spotlight


class MyApp(ShowBase):
    def __init__(self, screen_size = 50):
        ShowBase.__init__(self, windowType='offscreen')

        # Spotlight
        self.light = Spotlight('light')
        self.lightNP = self.render.attachNewNode(self.light)
        self.lightNP.setPos(0, 84, 75)
        self.lightNP.lookAt(0, 42, 0)
        self.render.setLight(self.lightNP)

        # Load the built-in RGB Cube.
        self.environ = self.loader.loadModel("models/misc/rgbCube")

        # Reparent the model to render.
        self.environ.reparentTo(self.render)

        # Apply scale and position transforms on the model.
        self.environ.setScale(10, 10, 10)
        self.environ.setPos(0, 42, 0)

    def get_camera_image(self):
        #Get image of panda3d offscreen buffer
        dr = self.camNode.getDisplayRegion(0)
        tex = dr.getScreenshot()
        data = tex.getRamImage().getData()
        sx = tex.getXSize()
        sy = tex.getYSize()

        #Convert Image to Pygame Image
        b,g,r,a = frombytes("RGBA", (sx, sy), data).split()
        pyGmImg = pygame.image.fromstring(merge("RGBA", (r, g, b, a)).tobytes(), (sx, sy), "RGBA", True)
        return pyGmImg

    def step(self):
        # Move the Cube
        self.environ.setHpr(((self.environ.getH() + globalClock.getDt() * 100),
                             (self.environ.getH() + globalClock.getDt() * 100),
                             (self.environ.getH() + globalClock.getDt() * 100)))
        #Render Image
        self.graphicsEngine.renderFrame()
        image = self.get_camera_image()
        return image


def main():
    #Initialise Pygame and Create Window
    pygame.init()
    PyWin = pygame.display.set_mode((800, 600))

    #Initialise Panda3d Application
    app = MyApp()

    running = True

    while running:
        #Make Panda3D Render Image
        image = app.step()

        #Display Image into Pygame Window
        PyWin.fill(0)
        PyWin.blit(image, (0, 0))

        #Update the Display
        pygame.display.flip()

        #Check for Quit event in Pygame
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                
                #Quit Pygame and Panda3D
                pygame.quit()
                app.destroy()
                running = False

if __name__ == '__main__':
    main()

NOTE:
If you have an issue with frombytes() or tobytes(), try changing it to the depreciated fromstring() or tostring(). But leave pygame.image.fromstring unchanged. This may be needed if you are using an older version of Pillow.

0
E R On

yes you can but

PyGame and Panda3D have their own main game loops its not recommended to use both loops

you can use panda3d to display 3D.

and use Pygame to do other things like play sound and handle inputs (Keyboard, mouse .... etc) Pygame easier than panda3d (from my POV)

you can't use both of them to display graphic (in real you can but its too hard and complex) instead try to use panda2d or onscreen Image, see this for more information.