示例#1
0
 def load_daytime_overrides(self, override_path):
     """ Loads an override file for the daytime settings, which contains
     values to override the settings with """
     overrides = load_yaml_file(override_path)
     if not overrides:
         self.warn("Failed to load daytime overrides")
         return
     for plugin_id, settings in iteritems(overrides["control_points"] or {}):
         for setting_id, control_points in iteritems(settings):
             if setting_id not in self.day_settings[plugin_id]:
                 self.warn("Unkown daytime override:", plugin_id, ":", setting_id)
                 continue
             self.day_settings[plugin_id][setting_id].set_control_points(control_points)
示例#2
0
 def save_daytime_overrides(self, override_file):
     """ Saves all time of day overrides to the given file """
     output = "\n# Render Pipeline Time Of Day Configuration\n"
     output += "# Instead of editing this file, prefer to use the Time Of Day Editor\n"
     output += "# Any formatting and comments will be lost\n\n"
     output += "control_points:\n"
     for plugin_id, settings in iteritems(self.day_settings):
         if settings:
             output += " " * 4 + plugin_id + ":\n"
             for setting_id, setting_handle in iteritems(settings):
                 output += " " * 8 + setting_id + ": "
                 output += setting_handle.serialize() + "\n"
     with open(override_file, "w") as handle:
         handle.write(output)
示例#3
0
    def load_settings(self):
        """ Loads all day time settings from the plugin manager and registers
        them to the used input buffer """
        for plugin_id, settings in iteritems(self._pipeline.plugin_mgr.day_settings):
            for setting, handle in iteritems(settings):
                setting_id = "{}.{}".format(plugin_id, setting)
                self._input_ubo.register_pta(setting_id, handle.glsl_type)
                self._setting_handles[setting_id] = handle
        self._pipeline.stage_mgr.input_blocks.append(self._input_ubo)

        # Generate UBO shader code
        shader_code = self._input_ubo.generate_shader_code()
        with open("/$$rptemp/$$daytime_config.inc.glsl", "w") as handle:
            handle.write(shader_code)
 def save_daytime_overrides(self, override_file):
     """ Saves all time of day overrides to the given file """
     output = "\n# Render Pipeline Time Of Day Configuration\n"
     output += "# Instead of editing this file, prefer to use the Time Of Day Editor\n"
     output += "# Any formatting and comments will be lost\n\n"
     output += "control_points:\n"
     for plugin_id, settings in iteritems(self.day_settings):
         if settings:
             output += " " * 4 + plugin_id + ":\n"
             for setting_id, setting_handle in iteritems(settings):
                 output += " " * 8 + setting_id + ": "
                 output += setting_handle.serialize() + "\n"
     with open(override_file, "w") as handle:
         handle.write(output)
示例#5
0
    def load_settings(self):
        """ Loads all day time settings from the plugin manager and registers
        them to the used input buffer """
        for plugin_id, settings in iteritems(
                self._pipeline.plugin_mgr.day_settings):
            for setting, handle in iteritems(settings):
                setting_id = "{}.{}".format(plugin_id, setting)
                self._input_ubo.register_pta(setting_id, handle.glsl_type)
                self._setting_handles[setting_id] = handle
        self._pipeline.stage_mgr.input_blocks.append(self._input_ubo)

        # Generate UBO shader code
        shader_code = self._input_ubo.generate_shader_code()
        with open("/$$rptemp/$$daytime_config.inc.glsl", "w") as handle:
            handle.write(shader_code)
示例#6
0
 def should_be_visible(self, settings):
     """ Evaluates whether the plugin should be visible, taking all display
     conditions into account """
     for key, val in iteritems(self.display_conditions):
         if settings[key].value != val:
             return False
     return True
示例#7
0
    def _generate_hash(cls, filename, options):
        """ Generates an unique hash for the effect. The effect hash is based
        on the filename and the configured options, and is ensured to make the
        effect unique. This is important to make sure the caching works as
        intended. All options not present in options are set to the default value"""

        # Set all options which are not present in the dict to its defaults
        options = {
            k: options.get(k, v)
            for k, v in iteritems(cls._DEFAULT_OPTIONS)
        }

        # Hash filename, make sure it has the right format and also resolve
        # it to an absolute path, to make sure that relative paths are cached
        # correctly (otherwise, specifying a different path to the same file
        # will cause a cache miss)
        filename = Filename(filename)
        filename.make_absolute()
        file_hash = str(hash(filename.to_os_generic()))

        # Hash the options, that is, sort the keys to make sure the values
        # are always in the same order, and then convert the flags to strings using
        # '1' for a set flag, and '0' for a unset flag
        options_hash = "".join([
            "1" if options[key] else "0" for key in sorted(iterkeys(options))
        ])
        return file_hash + "-" + options_hash
示例#8
0
 def set_options(self, options):
     """ Sets the effect options, overriding the default options """
     for key, val in iteritems(options):
         if key not in self._options:
             self.error("Unkown option:", key)
             continue
         self._options[key] = val
 def load_daytime_overrides(self, override_path):
     """ Loads an override file for the daytime settings, which contains
     values to override the settings with """
     overrides = load_yaml_file(override_path)
     if not overrides:
         self.warn("Failed to load daytime overrides")
         return
     for plugin_id, settings in iteritems(overrides["control_points"]
                                          or {}):
         for setting_id, control_points in iteritems(settings):
             if setting_id not in self.day_settings[plugin_id]:
                 self.warn("Unkown daytime override:", plugin_id, ":",
                           setting_id)
                 continue
             self.day_settings[plugin_id][setting_id].set_control_points(
                 control_points)
示例#10
0
    def _load_plugin_list(self):
        """ Reloads the whole plugin list """
        print("Loading plugin list")

        # Reset selection
        self._current_plugin = None
        self._current_plugin_instance = None
        self._set_settings_visible(False)

        # Plugins are all plugins in the plugins directory
        self._plugin_mgr.unload()
        self._plugin_mgr.load()

        self.lst_plugins.clear()
        plugins = sorted(iteritems(self._plugin_mgr.instances),
                         key=lambda plg: plg[1].name)

        for plugin_id, instance in plugins:

            item = QtGui.QListWidgetItem()
            item.setText(" " + instance.name)

            if self._plugin_mgr.is_plugin_enabled(plugin_id):
                item.setCheckState(QtCore.Qt.Checked)
            else:
                item.setCheckState(QtCore.Qt.Unchecked)

            item._plugin_id = plugin_id
            self.lst_plugins.addItem(item)
示例#11
0
    def _load_plugin_list(self):
        """ Reloads the whole plugin list """
        print("Loading plugin list")

        # Reset selection
        self._current_plugin = None
        self._current_plugin_instance = None
        self._set_settings_visible(False)

        # Plugins are all plugins in the plugins directory
        self._plugin_mgr.unload()
        self._plugin_mgr.load()

        self.lst_plugins.clear()
        plugins = sorted(iteritems(self._plugin_mgr.instances), key=lambda plg: plg[1].name)

        for plugin_id, instance in plugins:

            item = QtGui.QListWidgetItem()
            item.setText(" " + instance.name)

            if self._plugin_mgr.is_plugin_enabled(plugin_id):
                item.setCheckState(QtCore.Qt.Checked)
            else:
                item.setCheckState(QtCore.Qt.Unchecked)

            item._plugin_id = plugin_id
            self.lst_plugins.addItem(item)
示例#12
0
 def set_options(self, options):
     """ Sets the effect options, overriding the default options """
     for key, val in iteritems(options):
         if key not in self._options:
             self.error("Unkown option:", key)
             continue
         self._options[key] = val
示例#13
0
 def load_setting_overrides(self, override_path):
     """ Loads an override file for the settings, which contains values to
     override the settings with """
     overrides = load_yaml_file(override_path)
     if not overrides:
         self.warn("Failed to load overrides")
         return
     self.enabled_plugins = set(overrides["enabled"] or [])
     for plugin_id, pluginsettings in iteritems(overrides["overrides"] or {}):
         if plugin_id not in self.settings:
             self.warn("Unkown plugin in plugin config:", plugin_id)
             continue
         for setting_id, setting_val in iteritems(pluginsettings or {}):
             if setting_id not in self.settings[plugin_id]:
                 self.warn("Unkown override:", plugin_id, ":", setting_id)
                 continue
             self.settings[plugin_id][setting_id].set_value(setting_val)
示例#14
0
    def _update_settings_list(self):
        """ Updates the list of visible settings """

        self.settings_tree.clear()
        self._tree_widgets = []

        first_item = None

        for plugin_id, plugin in iteritems(self._plugin_mgr.instances):

            daytime_settings = self._plugin_mgr.day_settings[plugin_id]

            if not daytime_settings:
                # Skip plugins with empty settings
                continue

            plugin_head = QTreeWidgetItem(self.settings_tree)
            plugin_head.setText(0, plugin.name)
            plugin_head.setFlags(Qt.ItemIsEnabled)
            font = QFont()
            font.setBold(True)
            if not self._plugin_mgr.is_plugin_enabled(plugin_id):
                plugin_head.setText(0, plugin.name)
            plugin_head.setFont(0, font)

            # Display all settings
            for setting, setting_handle in iteritems(daytime_settings):
                setting_item = QTreeWidgetItem(plugin_head)
                setting_item.setText(0, setting_handle.label)
                if PYQT_VERSION == 4:
                    setting_item.setTextColor(0, QColor(150, 150, 150))
                else:
                    setting_item.setForeground(0, QColor(150, 150, 150))
                setting_item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
                setting_item._setting_id = setting
                setting_item._setting_handle = setting_handle
                setting_item._plugin_id = plugin_id
                setting_item.setToolTip(0, setting_handle.description)
                setting_item.setToolTip(1, setting_handle.description)
                self._tree_widgets.append((setting_handle, setting_item))
                if not first_item:
                    first_item = setting_item

        self.settings_tree.expandAll()
        if first_item:
            self.settings_tree.setCurrentItem(first_item)
示例#15
0
    def _update_settings_list(self):
        """ Updates the list of visible settings """

        self.settings_tree.clear()
        self._tree_widgets = []

        first_item = None

        for plugin_id, plugin in iteritems(self._plugin_mgr.instances):

            daytime_settings = self._plugin_mgr.day_settings[plugin_id]

            if not daytime_settings:
                # Skip plugins with empty settings
                continue

            plugin_head = QTreeWidgetItem(self.settings_tree)
            plugin_head.setText(0, plugin.name)
            plugin_head.setFlags(Qt.ItemIsEnabled)
            font = QFont()
            font.setBold(True)
            if not self._plugin_mgr.is_plugin_enabled(plugin_id):
                plugin_head.setText(0, plugin.name)
            plugin_head.setFont(0, font)

            # Display all settings
            for setting, setting_handle in iteritems(daytime_settings):
                setting_item = QTreeWidgetItem(plugin_head)
                setting_item.setText(0, setting_handle.label)
                if PYQT_VERSION == 4:
                    setting_item.setTextColor(0, QColor(150, 150, 150))
                else:
                    setting_item.setForeground(0, QColor(150, 150, 150))
                setting_item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
                setting_item._setting_id = setting
                setting_item._setting_handle = setting_handle
                setting_item._plugin_id = plugin_id
                setting_item.setToolTip(0, setting_handle.description)
                setting_item.setToolTip(1, setting_handle.description)
                self._tree_widgets.append((setting_handle, setting_item))
                if not first_item:
                    first_item = setting_item

        self.settings_tree.expandAll()
        if first_item:
            self.settings_tree.setCurrentItem(first_item)
示例#16
0
    def _render_current_settings(self):
        """ Renders the current plugin settings """
        settings = self._plugin_mgr.settings[self._current_plugin]

        # remove all rows
        while self.table_plugin_settings.rowCount() > 0:
            self.table_plugin_settings.removeRow(0)

        label_font = QtGui.QFont()
        label_font.setPointSize(10)
        label_font.setFamily("Segoe UI")

        desc_font = QtGui.QFont()
        desc_font.setPointSize(8)
        desc_font.setFamily("Segoe UI")

        for index, (name, handle) in enumerate(iteritems(settings)):
            if not handle.should_be_visible(settings):
                continue

            row_index = self.table_plugin_settings.rowCount()

            # Increase row count
            self.table_plugin_settings.insertRow(
                self.table_plugin_settings.rowCount())

            label = QtGui.QLabel()
            label.setText(handle.label)
            label.setWordWrap(True)
            label.setFont(label_font)

            if handle.shader_runtime or handle.runtime:
                # label.setBackground(QtGui.QColor(200, 255, 200, 255))
                label.setStyleSheet("background: rgba(162, 204, 128, 255);")
            else:
                label.setStyleSheet("background: rgba(230, 230, 230, 255);")

            label.setMargin(10)

            self.table_plugin_settings.setCellWidget(row_index, 0, label)

            item_default = QtGui.QTableWidgetItem()
            item_default.setText(str(handle.default))
            item_default.setTextAlignment(QtCore.Qt.AlignCenter)
            self.table_plugin_settings.setItem(row_index, 1, item_default)

            setting_widget = self._get_widget_for_setting(name, handle)
            self.table_plugin_settings.setCellWidget(row_index, 2,
                                                     setting_widget)

            label_desc = QtGui.QLabel()
            label_desc.setText(handle.description)
            label_desc.setWordWrap(True)
            label_desc.setFont(desc_font)
            label_desc.setStyleSheet("color: #555;padding: 5px;")

            self.table_plugin_settings.setCellWidget(row_index, 3, label_desc)
示例#17
0
 def save_overrides(self, override_file):
     """ Saves all overrides to the given file """
     output = "\n# Render Pipeline Plugin Configuration\n"
     output += "# Instead of editing this file, prefer to use the Plugin Configurator\n"
     output += "# Any formatting and comments will be lost\n\n"
     output += "enabled:\n"
     sort_criteria = lambda pid: ("A" if self.is_plugin_enabled(pid) else "B") + pid
     for plugin_id in sorted(self.settings, key=sort_criteria):
         output += "   {}- {}\n".format(
             " # " if plugin_id not in self.enabled_plugins else " ", plugin_id)
     output += "\n\noverrides:\n"
     for plugin_id, pluginsettings in sorted(iteritems(self.settings)):
         output += " " * 4 + plugin_id + ":\n"
         for setting_id, setting_handle in iteritems(pluginsettings):
             output += " " * 8 + "{}: {}\n".format(setting_id, setting_handle.value)
         output += "\n"
     with open(override_file, "w") as handle:
         handle.write(output)
示例#18
0
 def load_setting_overrides(self, override_path):
     """ Loads an override file for the settings, which contains values to
     override the settings with """
     overrides = load_yaml_file(override_path)
     if not overrides:
         self.warn("Failed to load overrides")
         return
     self.enabled_plugins = set(overrides["enabled"] or [])
     for plugin_id, pluginsettings in iteritems(overrides["overrides"]
                                                or {}):
         if plugin_id not in self.settings:
             self.warn("Unkown plugin in plugin config:", plugin_id)
             continue
         for setting_id, setting_val in iteritems(pluginsettings or {}):
             if setting_id not in self.settings[plugin_id]:
                 self.warn("Unkown override:", plugin_id, ":", setting_id)
                 continue
             self.settings[plugin_id][setting_id].set_value(setting_val)
    def bind_to(self, target):
        """ Binds all inputs of this UBO to the given target, which may be
        either a RenderTarget or a NodePath """

        for pta_name, pta_handle in iteritems(self.ptas):
            if self.use_ubo:
                target.set_shader_input(self.name + "_UBO." + pta_name, pta_handle)
            else:
                target.set_shader_input(self.name + "." + pta_name, pta_handle)
示例#20
0
    def _render_current_settings(self):
        """ Renders the current plugin settings """
        settings = self._plugin_mgr.settings[self._current_plugin]

        # remove all rows
        while self.table_plugin_settings.rowCount() > 0:
            self.table_plugin_settings.removeRow(0)

        label_font = QFont()
        label_font.setPointSize(10)
        label_font.setFamily("Roboto")

        desc_font = QFont()
        desc_font.setPointSize(8)
        desc_font.setFamily("Roboto")

        for index, (name, handle) in enumerate(iteritems(settings)):
            if not handle.should_be_visible(settings):
                continue

            row_index = self.table_plugin_settings.rowCount()

            # Increase row count
            self.table_plugin_settings.insertRow(
                self.table_plugin_settings.rowCount())

            label = QLabel()
            label.setText(handle.label)
            label.setWordWrap(True)
            label.setFont(label_font)

            if not (handle.shader_runtime or handle.runtime):
                label.setStyleSheet("color: #999;")

            if handle.display_conditions:
                label.setStyleSheet(label.styleSheet() + "padding-left: 10px;")

            label.setMargin(10)

            self.table_plugin_settings.setCellWidget(row_index, 0, label)

            item_default = QTableWidgetItem()
            item_default.setText(str(handle.default))
            item_default.setTextAlignment(Qt.AlignCenter)
            self.table_plugin_settings.setItem(row_index, 1, item_default)

            setting_widget = self._get_widget_for_setting(name, handle)
            self.table_plugin_settings.setCellWidget(row_index, 2,
                                                     setting_widget)

            label_desc = QLabel()
            label_desc.setText(handle.description)
            label_desc.setWordWrap(True)
            label_desc.setFont(desc_font)
            label_desc.setStyleSheet("color: #555;padding: 5px;")

            self.table_plugin_settings.setCellWidget(row_index, 3, label_desc)
示例#21
0
 def update(self):
     """ Internal update method which updates all day time settings """
     for setting_id, handle in iteritems(self._setting_handles):
         # XXX: Find a better interface for this. Without this fix, colors
         # are in the range 0 .. 255 in the shader.
         if isinstance(handle, ColorType):
             value = handle.get_value_at(self._time)
         else:
             value = handle.get_scaled_value_at(self._time)
         self._input_ubo.update_input(setting_id, value)
示例#22
0
    def bind_to(self, target):
        """ Binds all inputs of this UBO to the given target, which may be
        either a RenderTarget or a NodePath """

        for pta_name, pta_handle in iteritems(self.ptas):
            if self.use_ubo:
                target.set_shader_input(self.name + "_UBO." + pta_name,
                                        pta_handle)
            else:
                target.set_shader_input(self.name + "." + pta_name, pta_handle)
示例#23
0
 def remove_target(self, target):
     """ Removes a previously registered target. This unregisters the
     target, as well as removing it from the list of assigned targets. """
     target.remove()
     target_key = None
     for key, value_target in iteritems(self._targets):
         if target == value_target:
             target_key = key
             break
     del self._targets[target_key]
示例#24
0
 def update(self):
     """ Internal update method which updates all day time settings """
     for setting_id, handle in iteritems(self._setting_handles):
         # XXX: Find a better interface for this. Without this fix, colors
         # are in the range 0 .. 255 in the shader.
         if isinstance(handle, ColorType):
             value = handle.get_value_at(self._time)
         else:
             value = handle.get_scaled_value_at(self._time)
         self._input_ubo.update_input(setting_id, value)
示例#25
0
    def _render_current_settings(self):
        """ Renders the current plugin settings """
        settings = self._plugin_mgr.settings[self._current_plugin]

        # remove all rows
        while self.table_plugin_settings.rowCount() > 0:
            self.table_plugin_settings.removeRow(0)

        label_font = QFont()
        label_font.setPointSize(10)
        label_font.setFamily("Roboto")

        desc_font = QFont()
        desc_font.setPointSize(8)
        desc_font.setFamily("Roboto")

        for index, (name, handle) in enumerate(iteritems(settings)):
            if not handle.should_be_visible(settings):
                continue

            row_index = self.table_plugin_settings.rowCount()

            # Increase row count
            self.table_plugin_settings.insertRow(self.table_plugin_settings.rowCount())

            label = QLabel()
            label.setText(handle.label)
            label.setWordWrap(True)
            label.setFont(label_font)

            if not (handle.shader_runtime or handle.runtime ):
                label.setStyleSheet("color: #999;")

            if handle.display_conditions:
                label.setStyleSheet(label.styleSheet() + "padding-left: 10px;")

            label.setMargin(10)

            self.table_plugin_settings.setCellWidget(row_index, 0, label)

            item_default = QTableWidgetItem()
            item_default.setText(str(handle.default))
            item_default.setTextAlignment(Qt.AlignCenter)
            self.table_plugin_settings.setItem(row_index, 1, item_default)

            setting_widget = self._get_widget_for_setting(name, handle)
            self.table_plugin_settings.setCellWidget(row_index, 2, setting_widget)

            label_desc = QLabel()
            label_desc.setText(handle.description)
            label_desc.setWordWrap(True)
            label_desc.setFont(desc_font)
            label_desc.setStyleSheet("color: #555;padding: 5px;")

            self.table_plugin_settings.setCellWidget(row_index, 3, label_desc)
示例#26
0
    def _render_current_settings(self):
        """ Renders the current plugin settings """
        settings = self._plugin_mgr.settings[self._current_plugin]

        # remove all rows
        while self.table_plugin_settings.rowCount() > 0:
            self.table_plugin_settings.removeRow(0)

        label_font = QtGui.QFont()
        label_font.setPointSize(10)
        label_font.setFamily("Segoe UI")

        desc_font = QtGui.QFont()
        desc_font.setPointSize(8)
        desc_font.setFamily("Segoe UI")

        for index, (name, handle) in enumerate(iteritems(settings)):
            if not handle.should_be_visible(settings):
                continue

            row_index = self.table_plugin_settings.rowCount()

            # Increase row count
            self.table_plugin_settings.insertRow(self.table_plugin_settings.rowCount())

            label = QtGui.QLabel()
            label.setText(handle.label)
            label.setWordWrap(True)
            label.setFont(label_font)

            if handle.shader_runtime or handle.runtime:
                # label.setBackground(QtGui.QColor(200, 255, 200, 255))
                label.setStyleSheet("background: rgba(162, 204, 128, 255);")
            else:
                label.setStyleSheet("background: rgba(230, 230, 230, 255);")

            label.setMargin(10)

            self.table_plugin_settings.setCellWidget(row_index, 0, label)

            item_default = QtGui.QTableWidgetItem()
            item_default.setText(str(handle.default))
            item_default.setTextAlignment(QtCore.Qt.AlignCenter)
            self.table_plugin_settings.setItem(row_index, 1, item_default)

            setting_widget = self._get_widget_for_setting(name, handle)
            self.table_plugin_settings.setCellWidget(row_index, 2, setting_widget)

            label_desc = QtGui.QLabel()
            label_desc.setText(handle.description)
            label_desc.setWordWrap(True)
            label_desc.setFont(desc_font)
            label_desc.setStyleSheet("color: #555;padding: 5px;")

            self.table_plugin_settings.setCellWidget(row_index, 3, label_desc)
示例#27
0
 def init_defines(self):
     """ Initializes all plugin settings as a define, so they can be queried
     in a shader """
     for plugin_id in self.enabled_plugins:
         pluginsettings = self.settings[plugin_id]
         self._pipeline.stage_mgr.defines["HAVE_PLUGIN_{}".format(plugin_id)] = 1
         for setting_id, setting in iteritems(pluginsettings):
             if setting.shader_runtime or not setting.runtime:
                 # Only store settings which either never change, or trigger
                 # a shader reload when they change
                 setting.add_defines(plugin_id, setting_id, self._pipeline.stage_mgr.defines)
示例#28
0
    def _construct_shader_from_data(self, pass_id, stage, template_src, data):  # noqa # pylint: disable=too-many-branches
        """ Constructs a shader from a given dataset """
        injects = {"defines": []}

        for key, val in iteritems(self._options):
            if isinstance(val, bool):
                val_str = "1" if val else "0"
            else:
                val_str = str(val)
            injects["defines"].append("#define OPT_{} {}".format(
                key.upper(), val_str))

        injects["defines"].append("#define IN_" + stage.upper() + "_SHADER 1")
        injects["defines"].append("#define IN_" + pass_id.upper() +
                                  "_SHADER 1")
        injects["defines"].append("#define IN_RENDERING_PASS 1")

        # Parse dependencies
        if "dependencies" in data:
            injects["includes"] = []
            for dependency in data["dependencies"]:
                include_str = "#pragma include \"{}\"".format(dependency)
                injects["includes"].append(include_str)
            del data["dependencies"]

        # Append aditional injects
        for key, val in iteritems(data):
            if val is None:
                self.warn("Empty insertion: '" + key + "'")
                continue

            if isinstance(val, (list, tuple)):
                self.warn(
                    "Invalid syntax, you used a list but you should have used a string:"
                )
                self.warn(val)
                continue
            injects[key] = injects.get(key, []) + [i for i in val.split("\n")]

        cache_key = self.effect_name + "@" + stage + "-" + pass_id + "@" + self.effect_hash
        return self._process_shader_template(template_src, cache_key, injects)
示例#29
0
 def save_overrides(self, override_file):
     """ Saves all overrides to the given file """
     output = "\n# Render Pipeline Plugin Configuration\n"
     output += "# Instead of editing this file, prefer to use the Plugin Configurator\n"
     output += "# Any formatting and comments will be lost\n\n"
     output += "enabled:\n"
     sort_criteria = lambda pid: ("A" if self.is_plugin_enabled(pid) else
                                  "B") + pid
     for plugin_id in sorted(self.settings, key=sort_criteria):
         output += "   {}- {}\n".format(
             " # " if plugin_id not in self.enabled_plugins else " ",
             plugin_id)
     output += "\n\noverrides:\n"
     for plugin_id, pluginsettings in sorted(iteritems(self.settings)):
         output += " " * 4 + plugin_id + ":\n"
         for setting_id, setting_handle in iteritems(pluginsettings):
             output += " " * 8 + "{}: {}\n".format(setting_id,
                                                   setting_handle.value)
         output += "\n"
     with open(override_file, "w") as handle:
         handle.write(output)
示例#30
0
    def _parse_content(self, parsed_yaml):
        """ Internal method to construct the effect from a yaml object """
        for key, val in iteritems(parsed_yaml):
            self._parse_shader_template(key, val)

        # Create missing programs using the default options
        if "vertex" not in parsed_yaml:
            self._parse_shader_template("vertex", {})

        for key in self._PASSES:
            if key not in parsed_yaml:
                self._parse_shader_template(key, {})
示例#31
0
    def _parse_content(self, parsed_yaml):
        """ Internal method to construct the effect from a yaml object """
        for key, val in iteritems(parsed_yaml):
            self._parse_shader_template(key, val)

        # Create missing programs using the default options
        if "vertex" not in parsed_yaml:
            self._parse_shader_template("vertex", {})

        for key in self._PASSES:
            if key not in parsed_yaml:
                self._parse_shader_template(key, {})
示例#32
0
 def init_defines(self):
     """ Initializes all plugin settings as a define, so they can be queried
     in a shader """
     for plugin_id in self.enabled_plugins:
         pluginsettings = self.settings[plugin_id]
         self._pipeline.stage_mgr.defines["HAVE_PLUGIN_{}".format(
             plugin_id)] = 1
         for setting_id, setting in iteritems(pluginsettings):
             if setting.shader_runtime or not setting.runtime:
                 # Only store settings which either never change, or trigger
                 # a shader reload when they change
                 setting.add_defines(plugin_id, setting_id,
                                     self._pipeline.stage_mgr.defines)
示例#33
0
    def _register_stage_result(self, stage):
        """ Registers all produced pipes, inputs and defines from the given
        stage, so they can be used by later stages. """
        for pipe_name, pipe_data in (iteritems)(stage.produced_pipes):
            if isinstance(pipe_data, (SimpleInputBlock, GroupedInputBlock)):
                self.input_blocks[pipe_name] = pipe_data
                continue
            self.pipes[pipe_name] = pipe_data

        for define_name, data in iteritems(stage.produced_defines):
            if define_name in self.defines:
                self.warn("Stage", stage, "overrides define", define_name)
            self.defines[define_name] = data

        for input_name, data in iteritems(stage.produced_inputs):
            if input_name in self.inputs:
                self.warn("Stage", stage, "overrides input", input_name)

            if isinstance(data, (SimpleInputBlock, GroupedInputBlock)):
                self.input_blocks[input_name] = data
                continue

            self.inputs[input_name] = data
示例#34
0
    def _register_stage_result(self, stage):
        """ Registers all produced pipes, inputs and defines from the given
        stage, so they can be used by later stages. """
        for pipe_name, pipe_data in (iteritems)(stage.produced_pipes):
            if isinstance(pipe_data, (SimpleInputBlock, GroupedInputBlock)):
                self.input_blocks[pipe_name] = pipe_data
                continue
            self.pipes[pipe_name] = pipe_data

        for define_name, data in iteritems(stage.produced_defines):
            if define_name in self.defines:
                self.warn("Stage", stage, "overrides define", define_name)
            self.defines[define_name] = data

        for input_name, data in iteritems(stage.produced_inputs):
            if input_name in self.inputs:
                self.warn("Stage", stage, "overrides input", input_name)

            if isinstance(data, (SimpleInputBlock, GroupedInputBlock)):
                self.input_blocks[input_name] = data
                continue

            self.inputs[input_name] = data
示例#35
0
    def _construct_shader_from_data(self, pass_id, stage, template_src, data):  # noqa # pylint: disable=too-many-branches
        """ Constructs a shader from a given dataset """
        injects = {"defines": []}

        for key, val in iteritems(self._options):
            if isinstance(val, bool):
                val_str = "1" if val else "0"
            else:
                val_str = str(val)
            injects["defines"].append("#define OPT_{} {}".format(key.upper(), val_str))

        injects["defines"].append("#define IN_" + stage.upper() + "_SHADER 1")
        injects["defines"].append("#define IN_" + pass_id.upper() + "_SHADER 1")
        injects["defines"].append("#define IN_RENDERING_PASS 1")

        # Parse dependencies
        if "dependencies" in data:
            injects["includes"] = []
            for dependency in data["dependencies"]:
                include_str = "#pragma include \"{}\"".format(dependency)
                injects["includes"].append(include_str)
            del data["dependencies"]

        # Append aditional injects
        for key, val in iteritems(data):
            if val is None:
                self.warn("Empty insertion: '" + key + "'")
                continue

            if isinstance(val, (list, tuple)):
                self.warn("Invalid syntax, you used a list but you should have used a string:")
                self.warn(val)
                continue
            injects[key] = injects.get(key, []) + [i for i in val.split("\n")]

        cache_key = self.effect_name + "@" + stage + "-" + pass_id + "@" + self.effect_hash
        return self._process_shader_template(template_src, cache_key, injects)
示例#36
0
    def _create_previous_pipes(self):
        """ Creates a target for each last-frame's pipe, any pipe starting
        with the prefix 'Previous::' has to be stored and copied each frame. """
        if self.previous_pipes:
            self._prev_stage = UpdatePreviousPipesStage(self.pipeline)
            for prev_pipe, prev_tex in iteritems(self.previous_pipes):

                if prev_pipe not in self.pipes:
                    self.error("Attempted to use previous frame data from pipe",
                               prev_pipe, "- however, that pipe was never created!")
                    return False

                # Tell the stage to transfer the data from the current pipe to
                # the current texture
                self._prev_stage.add_transfer(self.pipes[prev_pipe], prev_tex)
            self._prev_stage.create()
            self.stages.append(self._prev_stage)
示例#37
0
    def _create_previous_pipes(self):
        """ Creates a target for each last-frame's pipe, any pipe starting
        with the prefix 'Previous::' has to be stored and copied each frame. """
        if self.previous_pipes:
            self._prev_stage = UpdatePreviousPipesStage(self.pipeline)
            for prev_pipe, prev_tex in iteritems(self.previous_pipes):

                if prev_pipe not in self.pipes:
                    self.error("Attempted to use previous frame data from pipe",
                               prev_pipe, "- however, that pipe was never created!")
                    return False

                # Tell the stage to transfer the data from the current pipe to
                # the current texture
                self._prev_stage.add_transfer(self.pipes[prev_pipe], prev_tex)
            self._prev_stage.create()
            self._prev_stage.set_dimensions()
            self.stages.append(self._prev_stage)
    def exec_compute_shader(self, shader_obj, shader_inputs, exec_size,
                            workgroup_size=(16, 16, 1)):
        """ Executes a compute shader. The shader object should be a shader
        loaded with Shader.load_compute, the shader inputs should be a dict where
        the keys are the names of the shader inputs and the values are the
        inputs. The workgroup_size has to match the size defined in the
        compute shader """
        ntx = int(math.ceil(exec_size[0] / workgroup_size[0]))
        nty = int(math.ceil(exec_size[1] / workgroup_size[1]))
        ntz = int(math.ceil(exec_size[2] / workgroup_size[2]))

        nodepath = NodePath("shader")
        nodepath.set_shader(shader_obj)
        for key, val in iteritems(shader_inputs):
            nodepath.set_shader_input(key, val)

        attr = nodepath.get_attrib(ShaderAttrib)
        Globals.base.graphicsEngine.dispatch_compute(
            (ntx, nty, ntz), attr, Globals.base.win.gsg)
    def exec_compute_shader(self, shader_obj, shader_inputs, exec_size,
                            workgroup_size=(16, 16, 1)):
        """ Executes a compute shader. The shader object should be a shader
        loaded with Shader.load_compute, the shader inputs should be a dict where
        the keys are the names of the shader inputs and the values are the
        inputs. The workgroup_size has to match the size defined in the
        compute shader """
        ntx = int(math.ceil(exec_size[0] / workgroup_size[0]))
        nty = int(math.ceil(exec_size[1] / workgroup_size[1]))
        ntz = int(math.ceil(exec_size[2] / workgroup_size[2]))

        nodepath = NodePath("shader")
        nodepath.set_shader(shader_obj)
        for key, val in iteritems(shader_inputs):
            nodepath.set_shader_input(key, val)

        attr = nodepath.get_attrib(ShaderAttrib)
        Globals.base.graphicsEngine.dispatch_compute(
            (ntx, nty, ntz), attr, Globals.base.win.get_gsg())
示例#40
0
    def write_autoconfig(self):
        """ Writes the shader auto config, based on the defines specified by the
        different stages """
        self.debug("Writing shader config")

        # Generate autoconfig as string
        output = "#pragma once\n\n"
        output += "// Autogenerated by the render pipeline\n"
        output += "// Do not edit! Your changes will be lost.\n\n"

        for key, value in sorted(iteritems(self.defines)):
            if isinstance(value, bool):
                value = 1 if value else 0
            output += "#define " + key + " " + str(value) + "\n"

        try:
            with open("/$$rptemp/$$pipeline_shader_config.inc.glsl", "w") as handle:
                handle.write(output)
        except IOError as msg:
            self.error("Error writing shader autoconfig:", msg)
示例#41
0
    def write_autoconfig(self):
        """ Writes the shader auto config, based on the defines specified by the
        different stages """
        self.debug("Writing shader config")

        # Generate autoconfig as string
        output = "#pragma once\n\n"
        output += "// Autogenerated by the render pipeline\n"
        output += "// Do not edit! Your changes will be lost.\n\n"

        for key, value in sorted(iteritems(self.defines)):
            if isinstance(value, bool):
                value = 1 if value else 0
            output += "#define " + key + " " + str(value) + "\n"

        try:
            with open("/$$rptemp/$$pipeline_shader_config.inc.glsl", "w") as handle:
                handle.write(output)
        except IOError as msg:
            self.error("Error writing shader autoconfig:", msg)
示例#42
0
    def _generate_hash(cls, filename, options):
        """ Generates an unique hash for the effect. The effect hash is based
        on the filename and the configured options, and is ensured to make the
        effect unique. This is important to make sure the caching works as
        intended. All options not present in options are set to the default value"""

        # Set all options which are not present in the dict to its defaults
        options = {k: options.get(k, v) for k, v in iteritems(cls._DEFAULT_OPTIONS)}

        # Hash filename, make sure it has the right format and also resolve
        # it to an absolute path, to make sure that relative paths are cached
        # correctly (otherwise, specifying a different path to the same file
        # will cause a cache miss)
        filename = Filename(filename)
        filename.make_absolute()
        file_hash = str(hash(filename.to_os_generic()))

        # Hash the options, that is, sort the keys to make sure the values
        # are always in the same order, and then convert the flags to strings using
        # '1' for a set flag, and '0' for a unset flag
        options_hash = ''.join(['1' if options[key] else '-' for key in sorted(iterkeys(options))])
        return file_hash + "-" + options_hash
示例#43
0
 def set_shader_inputs(self, **inputs):
     set_shader_input = self.set_shader_input
     for args in iteritems(inputs):
         set_shader_input(*args)
示例#44
0
    def _construct_shader_from_data(self, shader_id, default_template, data):
        """ Constructs a shader from a given dataset """
        injects = {}
        template_src = default_template

        # Check the template
        if "template" in data:
            data_template = data["template"]
            if data_template != "default":
                template_src = data_template

        # Add defines to the injects
        injects['defines'] = []
        for key, val in iteritems(self._options):
            val_str = str(val)
            if isinstance(val, bool):
                val_str = "1" if val else "0"
            injects['defines'].append("#define OPT_" + key.upper() + " " +
                                      val_str)

        # Parse dependencies
        if "dependencies" in data:
            injects["includes"] = []
            for dependency in data["dependencies"]:
                include_str = "#pragma include \"" + dependency + "\""
                injects["includes"].append(include_str)

        # Append inouts
        if "inout" in data:
            injects["inout"] = data["inout"]

        # Append aditional injects
        if "inject" in data:
            data_injects = data["inject"]
            for key, val in iteritems(data_injects):
                if val is None:
                    self.warn("Empty insertion: '" + key + "'")
                    continue

                if isinstance(val, (list, tuple)):
                    self.warn(
                        "Invalid syntax, you used a list but you should have used a string:"
                    )
                    self.warn(val)
                    continue
                val = [i for i in val.split("\n")]

                if key in injects:
                    injects[key] += val
                else:
                    injects[key] = val

        # Check for unrecognized keys
        for key in data:
            if key not in ["dependencies", "inout", "inject", "template"]:
                self.warn("Unrecognized key:", key)

        shader = ShaderTemplate(
            template_src,
            self._effect_name + "@" + shader_id + "@" + self._effect_hash)

        for key, val in iteritems(injects):
            shader.register_template_value(key, val)

        return shader.create()
 def glsl_type_to_pta(self, glsl_type):
     """ Converts a glsl type to a PtaXXX type """
     for key, val in iteritems(GroupedInputBlock.PTA_MAPPINGS):
         if val == glsl_type:
             return key
     self.error("Could not resolve GLSL type:", glsl_type)
    def generate_shader_code(self):
        """ Generates the GLSL shader code to use the UBO """

        content = "#pragma once\n\n"
        content += "// Autogenerated by the render pipeline\n"
        content += "// Do not edit! Your changes will be lost.\n\n"

        structs = {}
        inputs = []

        for input_name, handle in iteritems(self.ptas):
            parts = input_name.split(".")

            # Single input, simply add it to the input list
            if len(parts) == 1:
                inputs.append(self.pta_to_glsl_type(handle) + " " + input_name + ";")

            # Nested input, like scattering.sun_color
            elif len(parts) == 2:
                struct_name = parts[0]
                actual_input_name = parts[1]
                if struct_name in structs:
                    # Struct is already defined, add member definition
                    structs[struct_name].append(
                        self.pta_to_glsl_type(handle) + " " + actual_input_name + ";")
                else:
                    # Construct a new struct and add it to the list of inputs
                    inputs.append(struct_name + "_UBOSTRUCT " + struct_name + ";")
                    structs[struct_name] = [
                        self.pta_to_glsl_type(handle) + " " + actual_input_name + ";"
                    ]

            # Nested input, like scattering.some_setting.sun_color, not supported yet
            else:
                self.warn("Structure definition too nested, not supported (yet):", input_name)

        # Add structures
        for struct_name, members in iteritems(structs):
            content += "struct " + struct_name + "_UBOSTRUCT {\n"
            for member in members:
                content += " " * 4 + member + "\n"
            content += "};\n\n"

        # Add actual inputs
        if len(inputs) < 1:
            self.debug("No UBO inputs present for", self.name)
        else:
            if self.use_ubo:

                content += "layout(shared, binding={}) uniform {}_UBO {{\n".format(
                    self.bind_id, self.name)
                for ipt in inputs:
                    content += " " * 4 + ipt + "\n"
                content += "} " + self.name + ";\n"
            else:
                content += "uniform struct {\n"
                for ipt in inputs:
                    content += " " * 4 + ipt + "\n"
                content += "} " + self.name + ";\n"

        content += "\n"
        return content
示例#47
0
 def pta_to_glsl_type(self, pta_handle):
     """ Converts a PtaXXX to a glsl type """
     for pta_type, glsl_type in iteritems(GroupedInputBlock.PTA_MAPPINGS):
         if isinstance(pta_handle, pta_type):
             return glsl_type
     self.error("Unrecognized PTA type:", pta_handle)
示例#48
0
    def _populate_content(self):  # pylint: disable=too-many-branches,too-many-statements
        """ Reads the pipes and stages from the stage manager and renders those
        into the window """
        self._created = True
        self._pipe_node = self._content_node.attach_new_node("pipes")
        self._pipe_node.set_scale(1, 1, -1)
        self._stage_node = self._content_node.attach_new_node("stages")
        current_pipes = []
        pipe_pixel_size = 3
        pipe_height = 100

        # Generate stages
        for offs, stage in enumerate(self._STAGE_MGR.stages):
            node = self._content_node.attach_new_node("stage")
            node.set_pos(220 + offs * 200.0, 0, 20)
            node.set_scale(1, 1, -1)
            DirectFrame(parent=node, frameSize=(10, 150, 0, -3600),
                        frameColor=(0.2, 0.2, 0.2, 1))
            Text(text=str(stage.debug_name.replace("Stage", "")),
                 parent=node, x=20, y=25, size=15)

            for output_pipe, pipe_tex in iteritems(stage.produced_pipes):
                pipe_idx = 0
                r, g, b = rgb_from_string(output_pipe)
                if output_pipe in current_pipes:
                    pipe_idx = current_pipes.index(output_pipe)
                else:
                    current_pipes.append(output_pipe)
                    pipe_idx = len(current_pipes) - 1
                    DirectFrame(parent=node,
                                frameSize=(0, 8000, pipe_pixel_size / 2,
                                           -pipe_pixel_size / 2),
                                frameColor=(r, g, b, 1),
                                pos=(10, 1, -95 - pipe_idx * pipe_height))
                w = 160
                h = Globals.native_resolution.y /\
                    float(Globals.native_resolution.x) * w
                DirectFrame(parent=node,
                            frameSize=(-pipe_pixel_size, w + pipe_pixel_size,
                                       h / 2 + pipe_pixel_size,
                                       -h / 2 - pipe_pixel_size),
                            frameColor=(r, g, b, 1),
                            pos=(0, 1, -95 - pipe_idx * pipe_height))

                if isinstance(pipe_tex, (list, tuple)):
                    pipe_tex = pipe_tex[0]

                if isinstance(pipe_tex, (SimpleInputBlock, GroupedInputBlock)):
                    icon_file = "/$$rp/data/gui/icon_ubo.png"
                elif pipe_tex.get_z_size() > 1:
                    icon_file = "/$$rp/data/gui/icon_texture.png"
                elif pipe_tex.get_texture_type() == Texture.TT_buffer_texture:
                    icon_file = "/$$rp/data/gui/icon_buffer_texture.png"
                else:
                    icon_file = None
                    preview = Sprite(
                        image=pipe_tex, parent=node, x=0,
                        y=50 + pipe_idx * pipe_height, w=w, h=h, any_filter=False,
                        transparent=False)

                    preview_shader = DisplayShaderBuilder.build(pipe_tex, int(w), int(h))
                    preview.set_shader(preview_shader)

                    preview.set_shader_inputs(
                        mipmap=0,
                        slice=0,
                        brightness=1,
                        tonemap=False)

                if icon_file:
                    Sprite(image=icon_file, parent=node,
                           x=55, y=65 + pipe_idx * pipe_height,
                           w=48, h=48, near_filter=False,
                           transparent=True)

                    if isinstance(pipe_tex, (SimpleInputBlock, GroupedInputBlock)):
                        tex_desc = "UBO"
                    else:
                        tex_desc = pipe_tex.format_texture_type(pipe_tex.get_texture_type())
                        tex_desc += " - " + pipe_tex.format_format(pipe_tex.get_format()).upper()

                    Text(text=tex_desc, parent=node, x=55 + 48 / 2,
                         y=130 + pipe_idx * pipe_height, color=Vec3(0.2),
                         size=12, align="center")

            for input_pipe in stage.required_pipes:
                if input_pipe not in current_pipes:
                    self.warn("Pipe not found:", input_pipe)
                    continue
                idx = current_pipes.index(input_pipe)
                r, g, b = rgb_from_string(input_pipe)
                DirectFrame(parent=node, frameSize=(0, 10, 40, -40),
                            frameColor=(r, g, b, 1),
                            pos=(5, 1, -95 - idx * pipe_height))

        self._pipe_descriptions = self._content_node.attach_new_node(
            "PipeDescriptions")
        self._pipe_descriptions.set_scale(1, 1, -1)

        DirectFrame(parent=self._pipe_descriptions, frameSize=(0, 190, 0, -5000),
                    frameColor=(0.1, 0.1, 0.1, 1.0))

        # Generate the pipe descriptions
        for idx, pipe in enumerate(current_pipes):
            r, g, b = rgb_from_string(pipe)
            DirectFrame(parent=self._pipe_descriptions,
                        frameSize=(0, 180, -95, -135),
                        frameColor=(r, g, b, 1.0), pos=(0, 1, -idx * pipe_height))
            Text(parent=self._pipe_descriptions, text=pipe,
                 x=42, y=121 + idx * pipe_height, size=15,
                 color=Vec3(0.1))
            Sprite(parent=self._pipe_descriptions, x=9, y=103 + idx * pipe_height,
                   image="/$$rp/data/gui/icon_pipe.png",
                   transparent=True, near_filter=False)
示例#49
0
 def glsl_type_to_pta(self, glsl_type):
     """ Converts a glsl type to a PtaXXX type """
     for key, val in iteritems(GroupedInputBlock.PTA_MAPPINGS):
         if val == glsl_type:
             return key
     self.error("Could not resolve GLSL type:", glsl_type)
示例#50
0
    def generate_shader_code(self):
        """ Generates the GLSL shader code to use the UBO """

        content = "#pragma once\n\n"
        content += "// Autogenerated by the render pipeline\n"
        content += "// Do not edit! Your changes will be lost.\n\n"

        structs = {}
        inputs = []

        for input_name, handle in iteritems(self.ptas):
            parts = input_name.split(".")

            # Single input, simply add it to the input list
            if len(parts) == 1:
                inputs.append(
                    self.pta_to_glsl_type(handle) + " " + input_name + ";")

            # Nested input, like scattering.sun_color
            elif len(parts) == 2:
                struct_name = parts[0]
                actual_input_name = parts[1]
                if struct_name in structs:
                    # Struct is already defined, add member definition
                    structs[struct_name].append(
                        self.pta_to_glsl_type(handle) + " " +
                        actual_input_name + ";")
                else:
                    # Construct a new struct and add it to the list of inputs
                    inputs.append(struct_name + "_UBOSTRUCT " + struct_name +
                                  ";")
                    structs[struct_name] = [
                        self.pta_to_glsl_type(handle) + " " +
                        actual_input_name + ";"
                    ]

            # Nested input, like scattering.some_setting.sun_color, not supported yet
            else:
                self.warn(
                    "Structure definition too nested, not supported (yet):",
                    input_name)

        # Add structures
        for struct_name, members in iteritems(structs):
            content += "struct " + struct_name + "_UBOSTRUCT {\n"
            for member in members:
                content += " " * 4 + member + "\n"
            content += "};\n\n"

        # Add actual inputs
        if len(inputs) < 1:
            self.debug("No UBO inputs present for", self.name)
        else:
            if self.use_ubo:

                content += "layout(shared, binding={}) uniform {}_UBO {{\n".format(
                    self.bind_id, self.name)
                for ipt in inputs:
                    content += " " * 4 + ipt + "\n"
                content += "} " + self.name + ";\n"
            else:
                content += "uniform struct {\n"
                for ipt in inputs:
                    content += " " * 4 + ipt + "\n"
                content += "} " + self.name + ";\n"

        content += "\n"
        return content
示例#51
0
 def bind_to(self, target):
     """ Binds the UBO to a target """
     for key, val in iteritems(self.inputs):
         target.set_shader_input(self.name + "." + key, val)
示例#52
0
    def _construct_shader_from_data(self, shader_id, default_template, data):
        """ Constructs a shader from a given dataset """
        injects = {}
        template_src = default_template

        # Check the template
        if "template" in data:
            data_template = data["template"]
            if data_template != "default":
                template_src = data_template

        # Add defines to the injects
        injects['defines'] = []
        for key, val in iteritems(self._options):
            val_str = str(val)
            if isinstance(val, bool):
                val_str = "1" if val else "0"
            injects['defines'].append("#define OPT_" + key.upper() + " " + val_str)

        # Parse dependencies
        if "dependencies" in data:
            injects["includes"] = []
            for dependency in data["dependencies"]:
                include_str = "#pragma include \"" + dependency + "\""
                injects["includes"].append(include_str)

        # Append inouts
        if "inout" in data:
            injects["inout"] = data["inout"]

        # Append aditional injects
        if "inject" in data:
            data_injects = data["inject"]
            for key, val in iteritems(data_injects):
                if val is None:
                    self.warn("Empty insertion: '" + key + "'")
                    continue

                if isinstance(val, (list, tuple)):
                    self.warn("Invalid syntax, you used a list but you should have used a string:")
                    self.warn(val)
                    continue
                val = [i for i in val.split("\n")]

                if key in injects:
                    injects[key] += val
                else:
                    injects[key] = val

        # Check for unrecognized keys
        for key in data:
            if key not in ["dependencies", "inout", "inject", "template"]:
                self.warn("Unrecognized key:", key)

        shader = ShaderTemplate(
            template_src,
            self._effect_name + "@" + shader_id + "@" + self._effect_hash)

        for key, val in iteritems(injects):
            shader.register_template_value(key, val)

        return shader.create()
示例#53
0
    def _populate_content(self):  # pylint: disable=too-many-branches,too-many-statements
        """ Reads the pipes and stages from the stage manager and renders those
        into the window """
        self._created = True
        self._pipe_node = self._content_node.attach_new_node("pipes")
        self._pipe_node.set_scale(1, 1, -1)
        self._stage_node = self._content_node.attach_new_node("stages")
        current_pipes = []
        pipe_pixel_size = 3
        pipe_height = 100

        # Generate stages
        for offs, stage in enumerate(self._STAGE_MGR.stages):
            node = self._content_node.attach_new_node("stage")
            node.set_pos(220 + offs * 200.0, 0, 20)
            node.set_scale(1, 1, -1)
            DirectFrame(parent=node,
                        frameSize=(10, 150, 0, -3600),
                        frameColor=(0.2, 0.2, 0.2, 1))
            Text(text=str(stage.debug_name.replace("Stage", "")),
                 parent=node,
                 x=20,
                 y=25,
                 size=15)

            for output_pipe, pipe_tex in iteritems(stage.produced_pipes):
                pipe_idx = 0
                r, g, b = rgb_from_string(output_pipe)
                if output_pipe in current_pipes:
                    pipe_idx = current_pipes.index(output_pipe)
                else:
                    current_pipes.append(output_pipe)
                    pipe_idx = len(current_pipes) - 1
                    DirectFrame(parent=node,
                                frameSize=(0, 8000, pipe_pixel_size / 2,
                                           -pipe_pixel_size / 2),
                                frameColor=(r, g, b, 1),
                                pos=(10, 1, -95 - pipe_idx * pipe_height))
                w = 160
                h = Globals.native_resolution.y /\
                    float(Globals.native_resolution.x) * w
                DirectFrame(parent=node,
                            frameSize=(-pipe_pixel_size, w + pipe_pixel_size,
                                       h / 2 + pipe_pixel_size,
                                       -h / 2 - pipe_pixel_size),
                            frameColor=(r, g, b, 1),
                            pos=(0, 1, -95 - pipe_idx * pipe_height))

                if isinstance(pipe_tex, (list, tuple)):
                    pipe_tex = pipe_tex[0]

                if isinstance(pipe_tex, (SimpleInputBlock, GroupedInputBlock)):
                    icon_file = "/$$rp/data/gui/icon_ubo.png"
                elif pipe_tex.get_z_size() > 1:
                    icon_file = "/$$rp/data/gui/icon_texture.png"
                elif pipe_tex.get_texture_type() == Texture.TT_buffer_texture:
                    icon_file = "/$$rp/data/gui/icon_buffer_texture.png"
                else:
                    icon_file = None
                    preview = Sprite(image=pipe_tex,
                                     parent=node,
                                     x=0,
                                     y=50 + pipe_idx * pipe_height,
                                     w=w,
                                     h=h,
                                     any_filter=False,
                                     transparent=False)

                    preview_shader = DisplayShaderBuilder.build(
                        pipe_tex, int(w), int(h))
                    preview.set_shader(preview_shader)

                    preview.set_shader_inputs(mipmap=0,
                                              slice=0,
                                              brightness=1,
                                              tonemap=False)

                if icon_file:
                    Sprite(image=icon_file,
                           parent=node,
                           x=55,
                           y=65 + pipe_idx * pipe_height,
                           w=48,
                           h=48,
                           near_filter=False,
                           transparent=True)

                    if isinstance(pipe_tex,
                                  (SimpleInputBlock, GroupedInputBlock)):
                        tex_desc = "UBO"
                    else:
                        tex_desc = pipe_tex.format_texture_type(
                            pipe_tex.get_texture_type())
                        tex_desc += " - " + pipe_tex.format_format(
                            pipe_tex.get_format()).upper()

                    Text(text=tex_desc,
                         parent=node,
                         x=55 + 48 / 2,
                         y=130 + pipe_idx * pipe_height,
                         color=Vec3(0.2),
                         size=12,
                         align="center")

            for input_pipe in stage.required_pipes:
                if input_pipe not in current_pipes:
                    self.warn("Pipe not found:", input_pipe)
                    continue
                idx = current_pipes.index(input_pipe)
                r, g, b = rgb_from_string(input_pipe)
                DirectFrame(parent=node,
                            frameSize=(0, 10, 40, -40),
                            frameColor=(r, g, b, 1),
                            pos=(5, 1, -95 - idx * pipe_height))

        self._pipe_descriptions = self._content_node.attach_new_node(
            "PipeDescriptions")
        self._pipe_descriptions.set_scale(1, 1, -1)

        DirectFrame(parent=self._pipe_descriptions,
                    frameSize=(0, 190, 0, -5000),
                    frameColor=(0.1, 0.1, 0.1, 1.0))

        # Generate the pipe descriptions
        for idx, pipe in enumerate(current_pipes):
            r, g, b = rgb_from_string(pipe)
            DirectFrame(parent=self._pipe_descriptions,
                        frameSize=(0, 180, -95, -135),
                        frameColor=(r, g, b, 1.0),
                        pos=(0, 1, -idx * pipe_height))
            Text(parent=self._pipe_descriptions,
                 text=pipe,
                 x=42,
                 y=121 + idx * pipe_height,
                 size=15,
                 color=Vec3(0.1))
            Sprite(parent=self._pipe_descriptions,
                   x=9,
                   y=103 + idx * pipe_height,
                   image="/$$rp/data/gui/icon_pipe.png",
                   transparent=True,
                   near_filter=False)
示例#54
0
 def set_shader_inputs(self, **inputs):
     set_shader_input = self.set_shader_input
     for args in iteritems(inputs):
         set_shader_input(*args)
 def pta_to_glsl_type(self, pta_handle):
     """ Converts a PtaXXX to a glsl type """
     for pta_type, glsl_type in iteritems(GroupedInputBlock.PTA_MAPPINGS):
         if isinstance(pta_handle, pta_type):
             return glsl_type
     self.error("Unrecognized PTA type:", pta_handle)
示例#56
0
 def update(self):
     """ Internal update method which updates all day time settings """
     for setting_id, handle in iteritems(self._setting_handles):
         value = handle.get_scaled_value_at(self._time)
         self._input_ubo.update_input(setting_id, value)
 def bind_to(self, target):
     """ Binds the UBO to a target """
     for key, val in iteritems(self.inputs):
         target.set_shader_input(self.name + "." + key, val)