mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-29 18:06:37 +00:00
* The docs now explicitly tell people how to write UI scripts, then UI extensions, with as quick a start as possible, and go into detail in later documents. Use of the python module directly is also not featured prominently as this is a rare use-case for casual scripting needs.
87 lines
6.5 KiB
ReStructuredText
87 lines
6.5 KiB
ReStructuredText
Tutorial: UI extensions
|
|
=======================
|
|
|
|
This document outlines how to get started writing a UI extension.
|
|
|
|
Creating an extension
|
|
---------------------
|
|
|
|
RenderDoc UI extensions are python modules loaded from standard locations on disk, depending on your platform. On Windows it's :file:`%APPDATA%\\qrenderdoc\\extensions` and on linux it's ``~/.local/share/qrenderdoc/extensions``.
|
|
|
|
In any subdirectory under this path you can register an extension by creating a ``extension.json`` file with some metadata, and creating a python module starting with an ``__init__.py`` file.
|
|
|
|
.. figure:: ../imgs/Screenshots/ExtensionManager.png
|
|
|
|
Extension Manager: Configures installed extensions.
|
|
|
|
To streamline setup we will ask RenderDoc to create a new extension for us. Open the extension manager by opening the :guilabel:`Tools` menu and select :guilabel:`Manage Extensions`, then click the :guilabel:`Create New...` button and enter a package name such as ``tutorialext``. This will create the ``extension.json`` and ``__init__.py`` files in a new folder ``tutorialext`` for us.
|
|
|
|
For more information about the registration of python extensions see :doc:`../how/how_python_extension`
|
|
|
|
Loading the extension
|
|
---------------------
|
|
|
|
To load the extension, select it in the list in the extension manager and click the :guilabel:`Load` button. Python modules can't be unloaded but they can be reloaded if changes are made to the files on disk, so the button changes to :guilabel:`Reload`.
|
|
|
|
When the extension is loaded a ``register()`` function is called, which at the moment for us just prints a message. This message can be viewed in the output panel of the :doc:`python scripting <../window/python_scripting>` window, which you can jump to by clicking :guilabel:`View Output`. You can filter the output with the drop-down above the output text.
|
|
|
|
.. note::
|
|
The output this will not show any messages from before the window was opened - you can click :guilabel:`Reload` after opening the python scripting window to see some new messages.
|
|
|
|
To avoid bugs in extensions from making the UI unusable easily, python extensions are not loaded by default. Once you've loaded an extension if you wish to have it automatically load on startup, you can do so by enabling :guilabel:`Always Load`.
|
|
|
|
Editing your extension
|
|
----------------------
|
|
|
|
At this point you will have an ``extension.json`` and ``__init__.py`` in the ``extensions/tutorialext`` folder in your application data directory. These can be edited in the program of your choice, but we will use the python scripting window which can browse and open extension files for edit.
|
|
|
|
In the python scripting panel project sidebar, expand :guilabel:`UI Extensions` and :guilabel:`tutorialext` to open these two files and see the default-provided contents.
|
|
|
|
.. figure:: ../imgs/Screenshots/PythonUIProjectEditor.png
|
|
|
|
Python Scripting: Editing the files for a new UI extension.
|
|
|
|
We will add a UI button and new panel to demonstrate how UI extensions can provide user-interactive features. This is available as ``Tutorial: UI extension`` in the :guilabel:`Examples` section of the project explorer, though note that you will have to copy the code into your ``__init__.py`` as the example does not run on its own.
|
|
|
|
.. highlight:: python
|
|
.. literalinclude:: ui_extensions.py
|
|
|
|
If you edit the ``__init__.py`` you'll find that the RenderDoc status bar will notify you that as well as having one extension currently loaded the files have been changed on disk. Clicking the button in the status bar will reload the extension:
|
|
|
|
.. figure:: ../imgs/Screenshots/PythonExtensionModified.png
|
|
|
|
The RenderDoc status bar with a modified extension loaded
|
|
|
|
.. |plugin| image:: ../imgs/icons/plugin.png
|
|
|
|
After the extension has been reloaded, you can use the new extension menu item under the extension icon |plugin| in the event browser. The menu item will open a new panel with a scavenger hunt for the largest drawcall in your capture.
|
|
|
|
.. figure:: ../imgs/Screenshots/TutorialUIExtension.png
|
|
|
|
The new button and window added by the extension.
|
|
|
|
Breaking it down
|
|
----------------
|
|
|
|
This example demonstrates how you can bridge the gap between python scripts and UI elements. It shows how to add a menu item to one of the main interfaces - the event browser - and how to create a new UI panel with custom interactivity.
|
|
|
|
When our extension is loaded (or reloaded) the ``register()`` function we define is called with two parameters, the version of RenderDoc as a string e.g. ``"1.23"`` and the :class:`~qrenderdoc.CaptureContext` which is also available as a global ``pyrenderdoc``.
|
|
|
|
From the :class:`~qrenderdoc.CaptureContext` at ``pyrenderdoc`` that we used in the previous example, we can get access to :class:`~qrenderdoc.ExtensionManager` which gives us the option to create a UI. First we register a menu item (:meth:`~qrenderdoc.ExtensionManager.RegisterPanelMenu`) in the event browser's toolbar, providing a list of submenus and a callback to call when it is pressed.
|
|
|
|
.. tip::
|
|
|
|
There are multiple places where you can add a new menu item, explore the available enum values and functions here to see what options there are!
|
|
|
|
When the ``open_window`` callback is called, we create a new window using the :doc:`UI helpers <in_depth/miniqt>` in :class:`~qrenderdoc.MiniQtHelper`. Note that most RenderDoc builds ship with fully integrated python Qt access via PySide, but the full Qt API is quite complex and not necessary for simple quick UIs.
|
|
|
|
For the UI we create a groupbox with a label and a button. When the button is pressed, it updates the label based on where the :ref:`current event <currentevent>` is relative to the largest drawcall found in the capture. This is all contained within a top-level widget (:meth:`~qrenderdoc.MiniQtHelper.CreateToplevelWidget`)
|
|
|
|
Finally we use :meth:`~qrenderdoc.CaptureContext.AddDockWindow` to add the top-level widget into RenderDoc's docking system. Any widget can be added as a new top-level docking panel, but it is recommended that you use an explicit top-level widget to be able to use its callback when it is closed.
|
|
|
|
Next steps
|
|
----------
|
|
|
|
This shows how to expose user-visible tools to connect through to custom scripts which can be of varying complexity. At this point you hopefully have the starting point to begin exploring APIs available in the documentation or through autocomplete.
|
|
|
|
Up until now we have written everything within the RenderDoc UI to get started quickly. This is fine for writing small snippets of code, but we can also set up an external IDE for a better experience when writing larger or more complex extensions. |