Exemple #1
0
    def _create_components(self):
        """ Internal method to init the widgets components """

        self._node.hide()

        # Create the texture where the gui component is rendered inside
        self._storage_tex = Image.create_2d("ExposureDisplay", 140, 20, "RGBA8")
        self._storage_tex.set_clear_color(Vec4(0.2, 0.6, 1.0, 1.0))
        self._storage_tex.clear_image()

        self._bg_frame = DirectFrame(
            parent=self._node, frameColor=(0.1, 0.1, 0.1, 1.0),
            frameSize=(200, 0, -10, -85), pos=(0, 0, 0))

        self._display_img = Sprite(
            image=self._storage_tex, parent=self._node, w=140, h=20, x=20, y=50)

        self._display_txt = Text(
            text="Current Exposure".upper(), parent=self._node, x=160, y=40,
            size=13, color=Vec3(0.8), align="right")

        # Create the shader which generates the visualization texture
        self._cshader_node = ComputeNode("ExposureWidget")
        self._cshader_node.add_dispatch(140 // 10, 20 // 4, 1)

        self._cshader_np = self._node.attach_new_node(self._cshader_node)

        # Defer the further loading
        Globals.base.taskMgr.doMethodLater(1.0, self._late_init, "ExposureLateInit")
Exemple #2
0
    def _late_init(self, task):
        """ Gets called after the pipeline was initialized """
        self._display_txt = Text(text="40 ms",
                                 parent=self._node,
                                 x=20,
                                 y=25,
                                 size=13,
                                 color=Vec3(1),
                                 may_change=True)
        self._display_txt_bottom = Text(text="0 ms",
                                        parent=self._node,
                                        x=20,
                                        y=120,
                                        size=13,
                                        color=Vec3(1),
                                        may_change=True)

        # Create the shader which generates the visualization texture
        self._cshader_node = ComputeNode("FPSChartUpdateChart")
        self._cshader_node.add_dispatch(250 // 10, 120 // 4, 1)
        self._cshader_np = self._node.attach_new_node(self._cshader_node)

        self._cshader = RPLoader.load_shader(
            "/$$rp/shader/fps_chart.compute.glsl")
        self._cshader_np.set_shader(self._cshader)
        self._cshader_np.set_shader_input("DestTex", self._display_tex)
        self._cshader_np.set_shader_input("FPSValues", self._storage_buffer)
        self._cshader_np.set_shader_input("index", self._store_index)
        self._cshader_np.set_shader_input("maxMs", self._chart_ms_max)

        self._update_shader_node = ComputeNode("FPSChartUpdateValues")
        self._update_shader_node.add_dispatch(1, 1, 1)
        self._update_shader_np = self._node.attach_new_node(
            self._update_shader_node)
        self._ushader = RPLoader.load_shader(
            "/$$rp/shader/fps_chart_update.compute.glsl")
        self._update_shader_np.set_shader(self._ushader)
        self._update_shader_np.set_shader_input("DestTex",
                                                self._storage_buffer)
        self._update_shader_np.set_shader_input("index", self._store_index)
        self._update_shader_np.set_shader_input("currentData",
                                                self._current_ftime)

        Globals.base.addTask(self._update, "UpdateFPSChart", sort=-50)

        return task.done
    def add_text(self, text, color):
        """ Internal method to add a new text to the output """
        Text(
            x=Globals.native_resolution.x - 30, y=self._num_errors * 23,
            align="right", text=text, size=12, parent=self._error_node, color=color)

        self._num_errors += 1

        if self._num_errors > 30:
            self.clear_messages()
            self.add_error("Error count exceeded. Cleared errors ..")
Exemple #4
0
    def __init__(self,
                 parent=None,
                 x=0,
                 y=0,
                 chb_callback=None,
                 chb_args=None,
                 chb_checked=True,
                 text="",
                 text_size=16,
                 radio=False,
                 text_color=None,
                 expand_width=100,
                 enabled=True):
        """ Constructs a new checkbox, forwarding most of the elements to the
        underlying Checkbox and Text. """
        RPObject.__init__(self)
        if chb_args is None:
            chb_args = []

        if text_color is None:
            text_color = Vec3(1)

        if not enabled:
            text_color = Vec3(1.0, 0, 0.28)

        self.text_color = text_color

        self._checkbox = Checkbox(parent=parent,
                                  x=x,
                                  y=y,
                                  enabled=enabled,
                                  callback=chb_callback,
                                  extra_args=chb_args,
                                  checked=chb_checked,
                                  radio=radio,
                                  expand_width=expand_width)
        self._text = Text(x=x + 26,
                          y=y + 9 + text_size // 4,
                          text=text,
                          align="left",
                          parent=parent,
                          size=text_size,
                          color=text_color,
                          may_change=True)

        if enabled:
            self._checkbox.node.bind(DGG.WITHIN, self._on_node_enter)
            self._checkbox.node.bind(DGG.WITHOUT, self._on_node_leave)
Exemple #5
0
    def _create_components(self):
        """ Creates the window components """
        self._node = self._parent.attach_new_node("Window")
        self._node.set_pos(self._pos.x, 1, -self._pos.y)
        border_px = 1
        border_frame_size = (-border_px, self._width + border_px, border_px,
                             -self._height - border_px)
        self._border_frame = DirectFrame(pos=(0, 1, 0),
                                         frameSize=border_frame_size,
                                         frameColor=(24 / 255.0, 131 / 255.0,
                                                     215 / 255.0, 1),
                                         parent=self._node,
                                         state=DGG.NORMAL)
        self._background = DirectFrame(pos=(0, 1, 0),
                                       frameSize=(0, self._width, 0,
                                                  -self._height),
                                       frameColor=(0.1, 0.1, 0.1, 1.0),
                                       parent=self._node)
        self._title_bar = DirectFrame(
            pos=(0, 1, 0),
            frameSize=(0, self._width, 0, -25),
            # frameColor=(0.058, 0.058, 0.058, 1),
            frameColor=(1, 1, 1, 1),
            parent=self._node,
            state=DGG.NORMAL)
        self._window_title = Text(parent=self._node,
                                  x=8,
                                  y=17,
                                  text=self._title,
                                  size=13,
                                  color=Vec3(0.15),
                                  may_change=True)
        self._btn_close = DirectButton(
            relief=DGG.FLAT,
            pressEffect=1,
            pos=(self._width - 22, 1, -12),
            frameColor=(1.0, 0.2, 0.2, 0.5),
            parent=self._node,
            scale=(45 / 2, 1, 24 / 2),
            image="/$$rp/rpcore/data/gui/close_window.png")

        # Init bindings
        self._btn_close.set_transparency(TransparencyAttrib.M_alpha)
        self._btn_close.bind(DGG.B1CLICK, self._request_close)
        self._btn_close.bind(DGG.WITHIN, self._on_close_btn_hover)
        self._btn_close.bind(DGG.WITHOUT, self._on_close_btn_out)
        self._title_bar.bind(DGG.B1PRESS, self._start_drag)
        self._title_bar.bind(DGG.B1RELEASE, self._stop_drag)
Exemple #6
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)
    def _render_stages(self):
        """ Renders the stages to the window """

        self._remove_components()
        entries_per_row = 6
        aspect = Globals.native_resolution.y / Globals.native_resolution.x
        entry_width = 235
        entry_height = (entry_width - 20) * aspect + 55

        # Store already processed images
        processed = set()
        index = -1
        # Iterate over all stages
        for stage_tex in self._stages:
            if stage_tex in processed:
                continue
            processed.add(stage_tex)
            index += 1
            stage_name = stage_tex.get_name()

            xoffs = index % entries_per_row
            yoffs = index // entries_per_row
            node = self._content_node.attach_new_node("Preview")
            node.set_sz(-1)
            node.set_pos(10 + xoffs * (entry_width - 14), 1,
                         yoffs * (entry_height - 14 + 10))

            r, g, b = 0.2, 0.2, 0.2
            if isinstance(stage_tex, Image):
                r, g, b = 0.2, 0.4, 0.6

            stage_name = stage_name.replace("render_pipeline_internal:", "")
            parts = stage_name.split(":")
            stage_name = parts[-1]
            DirectFrame(parent=node,
                        frameSize=(7, entry_width - 17, -7,
                                   -entry_height + 17),
                        frameColor=(r, g, b, 1.0),
                        pos=(0, 0, 0))

            frame_hover = DirectFrame(parent=node,
                                      frameSize=(0, entry_width - 10, 0,
                                                 -entry_height + 10),
                                      frameColor=(0, 0, 0, 0),
                                      pos=(0, 0, 0),
                                      state=DGG.NORMAL)
            frame_hover.bind(DGG.ENTER,
                             partial(self._on_texture_hovered, frame_hover))
            frame_hover.bind(DGG.EXIT,
                             partial(self._on_texture_blurred, frame_hover))
            frame_hover.bind(DGG.B1PRESS,
                             partial(self._on_texture_clicked, stage_tex))

            Text(text=stage_name,
                 x=15,
                 y=29,
                 parent=node,
                 size=12,
                 color=Vec3(0.8))

            # Scale image so it always fits
            w, h = stage_tex.get_x_size(), stage_tex.get_y_size()
            padd_x, padd_y = 24, 57
            scale_x = (entry_width - padd_x) / max(1, w)
            scale_y = (entry_height - padd_y) / max(1, h)
            scale_factor = min(scale_x, scale_y)

            if stage_tex.get_texture_type() == Image.TT_buffer_texture:
                scale_factor = 1
                w = entry_width - padd_x
                h = entry_height - padd_y

            preview = Sprite(image=stage_tex,
                             w=scale_factor * w,
                             h=scale_factor * h,
                             any_filter=False,
                             parent=node,
                             x=7,
                             y=40,
                             transparent=False)

            preview.set_shader_input("mipmap", 0)
            preview.set_shader_input("slice", 0)
            preview.set_shader_input("brightness", 1)
            preview.set_shader_input("tonemap", False)

            preview_shader = DisplayShaderBuilder.build(
                stage_tex, scale_factor * w, scale_factor * h)
            preview.set_shader(preview_shader)

        num_rows = (index + entries_per_row) // entries_per_row

        self._set_scroll_height(50 + (entry_height - 14 + 10) * num_rows)
    def present(self, tex):
        """ "Presents" a given texture and shows the window """
        self._current_tex = tex

        self.set_title(tex.get_name())

        # tex.write(tex.get_name() + ".png")

        # Remove old content
        self._content_node.node().remove_all_children()

        w, h = tex.get_x_size(), tex.get_y_size()
        if h > 1:
            scale_x = (self._width - 40.0) / w
            scale_y = (self._height - 110.0) / h
            scale_f = min(scale_x, scale_y)
            display_w = scale_f * w
            display_h = scale_f * h

        else:
            display_w = self._width - 40
            display_h = self._height - 110

        image = Sprite(
            image=tex, parent=self._content_node, x=20, y=90, w=display_w,
            h=display_h, any_filter=False, transparent=False)
        description = ""

        # Image size
        description += "{:d} x {:d} x {:d}".format(
            tex.get_x_size(), tex.get_y_size(), tex.get_z_size())

        # Image type
        description += ", {:s}, {:s}".format(
            Image.format_format(tex.get_format()).upper(),
            Image.format_component_type(tex.get_component_type()).upper())

        Text(text=description, parent=self._content_node, x=17, y=70,
             size=16, color=Vec3(0.6, 0.6, 0.6))

        estimated_bytes = tex.estimate_texture_memory()
        size_desc = "Estimated memory: {:2.2f} MB".format(
            estimated_bytes / (1024.0 ** 2))

        Text(text=size_desc, parent=self._content_node, x=self._width - 20.0,
             y=70, size=18, color=Vec3(0.34, 0.564, 0.192), align="right")

        x_pos = len(size_desc) * 9 + 140

        # Slider for viewing different mipmaps
        if tex.uses_mipmaps():
            max_mips = tex.get_expected_num_mipmap_levels() - 1
            self._mip_slider = Slider(
                parent=self._content_node, size=140, min_value=0, max_value=max_mips,
                callback=self._set_mip, x=x_pos, y=65, value=0)
            x_pos += 140 + 5

            self._mip_text = Text(
                text="MIP: 5", parent=self._content_node, x=x_pos, y=72, size=18,
                color=Vec3(1, 0.4, 0.4), may_change=1)
            x_pos += 50 + 30

        # Slider for viewing different Z-layers
        if tex.get_z_size() > 1:
            self._slice_slider = Slider(
                parent=self._content_node, size=250, min_value=0,
                max_value=tex.get_z_size() - 1, callback=self._set_slice, x=x_pos,
                y=65, value=0)
            x_pos += 250 + 5

            self._slice_text = Text(
                text="Z: 5", parent=self._content_node, x=x_pos, y=72, size=18,
                color=Vec3(0.4, 1, 0.4), may_change=1)

            x_pos += 50 + 30

        # Slider to adjust brightness
        self._bright_slider = Slider(
            parent=self._content_node, size=140, min_value=-14, max_value=14,
            callback=self._set_brightness, x=x_pos, y=65, value=0)
        x_pos += 140 + 5
        self._bright_text = Text(
            text="Bright: 1", parent=self._content_node, x=x_pos, y=72, size=18,
            color=Vec3(0.4, 0.4, 1), may_change=1)
        x_pos += 100 + 30

        # Slider to enable reinhard tonemapping
        self._tonemap_box = LabeledCheckbox(
            parent=self._content_node, x=x_pos, y=60, text="Tonemap",
            text_color=Vec3(1, 0.4, 0.4), chb_checked=False,
            chb_callback=self._set_enable_tonemap,
            text_size=18, expand_width=90)
        x_pos += 90 + 30

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

        preview_shader = DisplayShaderBuilder.build(tex, display_w, display_h)
        image.set_shader(preview_shader)

        self._preview_image = image
        self.show()