Not quite a ShowBase replacement yet

Inspired by @janEntikan1 's work, I’ve also started putting how ShowBase should work into code. Instead of going the “simple and close to the API” route, I went for “I just want to declare how my render pipeline from camera to window looks like, and let the code do the work of setting it up. In fact, I want to throw another specification at an already existing renderer, have it extended where needed, and the things I don’t use anymore broken down again.” The result so far is SpecBase. The demo program looks like this:

from panda3d.core import Vec4

from specbase import SpecBase
from specbase import load_model, refov
from specbase import RendererElement
from specbase import SBWindow, SBSceneGraph, SBCamera, SBDisplayRegion, SBKeep



spec = {
    RendererElement.WINDOW: [SBWindow('win')],
    RendererElement.SCENE_GRAPH: [SBSceneGraph('render')],
    RendererElement.CAMERA: [SBCamera('cam')],
    RendererElement.DISPLAY_REGION: [SBDisplayRegion('win_dr3d', 'win', 'cam', dimensions=Vec4(0.0, 0.5, 0.0, 1.0))],
}
SpecBase(spec)

# Now that the renderer exists, we can set up the scene.
base.cam.reparent_to(base.render)
base.cam.set_y(-10)
refov(base.cam, base.win)
model = load_model("models/smiley")
model.reparent_to(base.render)
base.step()  # Let's render what's there already.

# We can change the spec at runtime by providing the intended state.
new_spec = {
    RendererElement.WINDOW: [SBKeep('win'), SBWindow('win_2')],
    RendererElement.SCENE_GRAPH: [SBKeep('render')],
    RendererElement.CAMERA: [SBKeep('cam'), SBCamera('cam_2')],
    RendererElement.DISPLAY_REGION: [SBKeep('win_dr3d'), SBDisplayRegion('win_dr3d_2', 'win_2', 'cam_2', dimensions=Vec4(0.5, 1.0, 0.0, 1.0))],
}
base.respec(new_spec)


base.cam_2.reparent_to(base.render)
base.cam_2.set_h(45)
base.cam_2.set_y(base.cam_2, -10)
refov(base.cam_2, base.win)
base.step()

# Let's close the first window.
new_spec = {
    RendererElement.WINDOW: [SBKeep('win_2')],
    RendererElement.SCENE_GRAPH: [SBKeep('render')],
    RendererElement.CAMERA: [SBKeep('cam_2')],
    RendererElement.DISPLAY_REGION: [SBKeep('win_dr3d_2')],
}
base.respec(new_spec)


base.run()

While things are working pretty well so far, there is of course quite some jank and missing feature. However, before I progress too far, I’d like to ask all of you: What would be a better format for the specification?

1 Like

Well, this is simpler, I guess:

from panda3d.core import Vec4

from specbase import SpecBase
from specbase import SBWindow, SBSceneGraph, SBCamera, SBDisplayRegion
from specbase import load_model, refov


first_spec = [
    SBWindow('win'),
    SBSceneGraph('render'),
    SBCamera('cam'),
    SBDisplayRegion('win_dr3d', 'win', 'cam', dimensions=Vec4(0.0, 0.5, 0.0, 1.0))
]
SpecBase(first_spec)

# Now that the renderer exists, we can set up the scene.
base.cam.reparent_to(base.render)
base.cam.set_y(-10)
refov(base.cam, base.win)
model = load_model("models/smiley")
model.reparent_to(base.render)
base.step()  # Let's render what's there already.

# We can change the spec at runtime by providing the intended state.
second_spec = first_spec + [
    SBWindow('win_2'),
    SBCamera('cam_2'),
    SBDisplayRegion('win_dr3d_2', 'win_2', 'cam_2', dimensions=Vec4(0.5, 1.0, 0.0, 1.0)),
]

base.respec(second_spec)


base.cam_2.reparent_to(base.render)
base.cam_2.set_h(45)
base.cam_2.set_y(base.cam_2, -10)
refov(base.cam_2, base.win)
base.step()


# Let's close the first window.
third_spec = [
    SBWindow('win_2'),
    SBSceneGraph('render'),
    SBCamera('cam_2'),
    SBDisplayRegion('win_dr3d_2'),
]
base.respec(third_spec)


base.run()
1 Like

Nice. I was hoping working on a direct alternative would lead to this kind of thing. Soon writers of panda3d modules will have no choice but to write in a non-ShowBase manner muhahahaha ~queue lightning~

1 Like