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")
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 ..")
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)
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)
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()