Using Panda3D without "direct"

This is a minimal sample program showing how to open a window and render a model without using ShowBase, or indeed, any part of the direct module. This may be useful for certain low-level usage of Panda where ShowBase would just get in the way, or just for better understanding Panda under the hood.

from panda3d.core import *

engine = GraphicsEngine.get_global_ptr()
pipe = GraphicsPipeSelection.get_global_ptr().make_default_pipe()

# Open a window with requested properties
fb_prop = FrameBufferProperties()
fb_prop.rgb_color = 1
fb_prop.color_bits = 3 * 8
fb_prop.depth_bits = 24
fb_prop.back_buffers = 1
win = engine.make_output(pipe, name="window", sort=0, fb_prop=fb_prop,
                         win_prop=WindowProperties(size=(800, 600)),
                         flags=GraphicsPipe.BF_require_window)

# Set a grey background color
win.set_clear_color_active(True)
win.set_clear_color((0.5, 0.5, 0.5, 1))

# Create a scene and camera to render
render = NodePath("render")
cam = render.attach_new_node(Camera("camera"))
cam.node().set_lens(PerspectiveLens())

# Load a model into the scene
loader = Loader.get_global_ptr()
model = render.attach_new_node(loader.load_sync("panda.egg"))
model.set_pos(0, 100, 0)

# Create a display region that renders this scene
dr = win.make_display_region()
dr.camera = cam

# You could use the task manager and create a task that does this,
# but I wanted to show how to do it directly
while not win.is_closed():
    engine.render_frame()
7 Likes

Neat! So “direct” is just a big collection of utility functions?

“direct” - think of it as a library with game features.
“ShowBase” - the application template.

Sort of—the intent of “direct” is that it makes it really easy to create prototypes with the aid of a bunch of high-level Python classes that are easier to use than the C++ lower-level classes.

You can do pretty much anything you can do with direct directly with panda3d.core as well, it just takes more code.

I’m wondering why the model looks flattened and flat. Is it because of the lack of a depth buffer?

Yes! Good catch. Updated the code to request a depth buffer.

There is still not enough input device for the window.

Hi

I’ve been using Panda3D casually for a short while now for fun, I tried using the script you posted and tried to add lights(just the lines of code for the lights, and the model dissapeared)

This is the code I used.

from panda3d.core import *

engine = GraphicsEngine.get_global_ptr()
pipe = GraphicsPipeSelection.get_global_ptr().make_default_pipe()

# Open a window with requested properties
fb_prop = FrameBufferProperties()
fb_prop.rgb_color = 1
fb_prop.color_bits = 3 * 8
fb_prop.depth_bits = 24
fb_prop.back_buffers = 1
win = engine.make_output(pipe, name="window", sort=0, fb_prop=fb_prop,
                         win_prop=WindowProperties(size=(800, 600)),
                         flags=GraphicsPipe.BF_require_window)

# Set a grey background color
win.set_clear_color_active(True)
win.set_clear_color((0.5, 0.5, 0.5, 1))

# Create a scene and camera to render
render = NodePath("render")
cam = render.attach_new_node(Camera("camera"))
cam.node().set_lens(PerspectiveLens())

# Load a model into the scene
loader = Loader.get_global_ptr()
model = render.attach_new_node(loader.load_sync('model.egg'))
model.set_pos(0, 20, 0)

# Create a display region that renders this scene
dr = win.make_display_region()
dr.camera = cam


ambientLight = AmbientLight('ambientLight')
ambientLight.setColor((0.1, 0.1, 0.1, 1))
ambientLightNP = render.attachNewNode(ambientLight)
render.setLight(ambientLightNP)

# You could use the task manager and create a task that does this,
# but I wanted to show how to do it directly
while not win.is_closed():
    engine.render_frame()

Am I doing something wrong with how I tried to added lights? or is direct needed to add lighting?

No, this has nothing to do with the use of direct. Which exporter did you use? If you used the unsupported fork of YABEE, it is not designed for general use with Panda3D, and has bugs such as the fact that it writes materials with an alpha value of 0. Use blend2bam instead.

Thanks for the example!

So we can make multiple scenes each with its own camera. Then to change the scene we just have to do?:

dr.camera = camera2

Yes. (more words to fill out minimum post length)

1 Like

Thanks. I’d used the exporter plugin added to blender before

This is the code for the direct:

from direct.showbase.ShowBase

class Game(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        
        self.panda = self.loader.loadModel("models/panda")
        self.panda.setPos(0, 100, 0)
        self.panda.reparentTo(self.render)

game = Game()
game.run()

And this is the code for the panda3d module:

from panda3d.core import *

engine = GraphicsEngine.get_global_ptr()
pipe = GraphicsPipeSelection.get_global_ptr().make_default_pipe()

# Open a window with requested properties
fb_prop = FrameBufferProperties()
fb_prop.rgb_color = 1
fb_prop.color_bits = 3 * 8
fb_prop.depth_bits = 24
fb_prop.back_buffers = 1
win = engine.make_output(pipe, name="window", sort=0, fb_prop=fb_prop,
                         win_prop=WindowProperties(size=(800, 600)),
                         flags=GraphicsPipe.BF_require_window)

# Set a grey background color
win.set_clear_color_active(True)
win.set_clear_color((0.5, 0.5, 0.5, 1))

# Create a scene and camera to render
render = NodePath("render")
cam = render.attach_new_node(Camera("camera"))
cam.node().set_lens(PerspectiveLens())

# Load a model into the scene
loader = Loader.get_global_ptr()
model = render.attach_new_node(loader.load_sync("panda.egg"))
model.set_pos(0, 100, 0)

# Create a display region that renders this scene
dr = win.make_display_region()
dr.camera = cam

# You could use the task manager and create a task that does this,
# but I wanted to show how to do it directly
while not win.is_closed():
    engine.render_frame()

Using direct is clearly more easier.

Yes, obviously, that’s why direct exists.

So it means that direct was made in panda3d.core to make it simpler and direct runs the code that @rdb has shown?