Panda3D - Basic

Introduction

To start a Panda3D project using uv - Project, follow these steps:

Terminal window
uv init panda
cd panda
uv add panda3d

Now, let’s write the code to open a blank game window.

Replace the contents of main.py with the following three lines of code:

from direct.showbase.ShowBase import ShowBase
app = ShowBase()
app.run()

Even though it’s only three lines, let’s translate what you just wrote into plain English:

from direct.showbase.ShowBase import ShowBase

Think of this like going to a library. You are telling Python: “Go into the Panda3D library (direct.showbase), find the specific blueprint called ShowBase, and bring it here.” ShowBase is basically the master switch that turns on the game engine.

app = ShowBase()

Here, you are saying: “Create a new game using that blueprint, and let’s name it app.”

app.run()

This is you yelling “Action!” to your crew. It tells the game to start running and keep the window open until you click the X to close it.

Square

Creating a square in Panda3D is a bit different than in a 2D drawing app. Since Panda3D is a 3D engine, you’re usually creating a “flat 3D object” called a Quad.

The most efficient way to do this is by using the CardMaker class. It’s a handy utility designed specifically to generate flat, rectangular geometry without you having to manually define every vertex and triangle.

Here is the most straightforward way to get a square onto your screen:

from direct.showbase.ShowBase import ShowBase
from panda3d.core import CardMaker
app = ShowBase()
cm = CardMaker("square")
# 2. Define the dimensions (left, right, bottom, top)
# This creates a 2x2 square centered at the origin
cm.setFrame(-1, 1, -1, 1)
# 3. Generate the geometry and attach it to the scene (render)
square = app.render.attachNewNode(cm.generate())
# Move the camera back so we can see it
app.cam.setPos(0, -10, 0)
app.run()

Key Things to Know

  • setFrame(left, right, bottom, top): This defines the boundaries of your square. If you want a 1x1 unit square starting at the origin, you would use cm.setFrame(0, 1, 0, 1).

  • Single-Sided: By default, Panda3D objects are single-sided to save performance. If you rotate the square 180°, it will disappear. To make it visible from both sides, use: Python

    self.square.setTwoSided(True)

  • Positioning: Once generated, the square behaves like any other NodePath. You can move, rotate, or scale it using square.setPos(x, y, z) or square.setScale(2).

While you could manually define the vertices using GeomVertexData (the “procedural” way), it’s significantly more code—about 30–40 lines just to define four points and two triangles. CardMaker handles the heavy lifting, including setting up the UV coordinates so you can apply textures immediately.