Skip to content

Plugin API

tobspr edited this page Nov 12, 2015 · 18 revisions

Main-Class

Each plugin should consist of a Plugin base class which derives from BasePlugin. This is the default Plugin.py from the Plugin Prefab:

# Load the plugin api
from .. import *

# Load your additional plugin classes here, if required

class Plugin(BasePlugin):

    def __init__(self, pipeline):
        BasePlugin.__init__(self, pipeline)

    @PluginHook("on_stage_setup"):
    def setup_stages(self):
        """ This method gets called when the pipeline setups the render
        stages. You should create your custom stages here """

    @PluginHook("on_pipeline_created")
    def on_created(self):
        """ This method gets called after the pipeline finished the setup,
        and is about to start rendering """

    @SettingChanged("some_setting")
    def update_some_setting(self):
        """ This method gets called when the setting "some_setting"
        of your plugin gets called. You should do all work to update required
        inputs etc. yourself. """

Hooks

Each plugin can specify hooks it would like to bind to. When a hook gets triggered, your function bound to that hook will get called. You can find a list of hooks here: [Plugin Hooks](Plugin Hooks). Binding to a hook looks like this:

@PluginHook("hook_name")
def my_method(self):
    # Do something
    pass

Setting changes

When a setting gets changed, which is marked as runtime or shader_runtime (see [Plugin Configuration](Plugin Configuration)), you can specify a custom handler which gets called then. For example, to bind to the setting "my_setting", you would use:

@SettingChanged("my_setting")
def my_method(self):
    # Do some work here, e.g. update shader inputs and so on
    pass

Available Plugin methods

The base plugin class provides some methods, here is a list of them:

get_setting(setting_name)

This returns the value of the setting named by "setting_name". Throws an exception if the setting does not exist.

get_resource(resource_path)

Returns the absolute path to a resource, e.g. if you have a file named tex.png in your Resource/ folder, you should call self.get_resource("tex.png") to get the path to it.

get_shader_resource(shader_path)

Returns the absolute path to a shader, e.g. if you have a shader named my_shader.inc.glsl stored in Shader/, you should call self.get_shader_resource("my_shader.inc.glsl") to get the path to it.

create_stage(stage_type)

This method expects the classname of a stage (which derives from RenderStage). It should only be called in the on_stage_setup hook! It creates an instance of that stage, registers it, and returns the handle to that stage.

Example usage (assuming you have a class MyStage which derives from RenderStage):

@PluginHook("on_stage_setup")
def stage_setup(self):
    self._stage = self.create_stage(MyStage)

add_define(name, value)

Adds a define which can be used in all shaders, this should only be called in the on_stage_setup hook!.

exec_compute_shader(shader_obj, shader_inputs, exec_size, workgroup_size)

This is a handy function to execute a compute shader instantly. shader_obj should be a handle to a Panda3D Shader object. shader_inputs should be a dictionary of all shader inputs available to that compute shader. workgroup_size should be the layout size of the compute shader (those specified as layout(local_size_x=xxx, ...) in the shader). exec_size should be the size of the compute shader.