Skip to content

Plugin API

tobspr edited this page Apr 15, 2016 · 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 base plugin class
from rpcore.pluginbase.base_plugin import BasePlugin

# Load your additional plugin classes here, if required
from .demo_stage import DemoStage

class Plugin(BasePlugin):

    name = "Plugin Prefab"
    author = "tobspr <tobias.springer1@gmail.com>"
    description = ("This is the most basic structure of a plugin. You can copy "
                   "it to produce your own plugins")
    version = "1.0"

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

        # Setup a demo stage
        self.stage = self.create_stage(DemoStage)

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

    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:

def hook_name(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:

def update_my_setting(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_daytime_setting(setting_name, plugin_id = None)

This returns the value of the daytime setting named by "setting_name". Throws an exception if the setting does not exist. The plugin_id can be used to access the daytime settings of other plugins.


is_plugin_loaded(plugin_id)

Returns whether a plugin with the given id is currently enabled and loaded.


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.