def create_hints(self): """ Creates the hints like keybindings and when reloading shaders """ self.hint_reloading = Sprite( image="/$$rp/data/gui/shader_reload_hint.png", parent=self.fullscreen_node) self.set_reload_hint_visible(False) self.python_warning = None if not NATIVE_CXX_LOADED: # Warning when using the python version self.python_warning = Sprite( image="/$$rp/data/gui/python_warning.png", parent=self.fullscreen_node) Sequence( self.python_warning.color_scale_interval(0.7, Vec4(0.3, 1, 1, 0.7), blendType="easeOut"), self.python_warning.color_scale_interval(0.7, Vec4(1, 1, 1, 1.0), blendType="easeOut"), ).loop() # Keybinding hints self.keybinding_instructions = Sprite( image="/$$rp/data/gui/keybindings.png", parent=self.fullscreen_node, any_filter=False)
def _create_hints(self): """ Creates the hints like keybindings and when reloading shaders """ self._hint_reloading = Sprite( image="/$$rp/data/gui/shader_reload_hint.png", x=float((Globals.base.win.get_x_size()) // 2) / self._gui_scale - 465 // 2, y=220, parent=self._fullscreen_node) self.set_reload_hint_visible(False) if not NATIVE_CXX_LOADED: # Warning when using the python version python_warning = Sprite( image="/$$rp/data/gui/python_warning.png", x=((Globals.base.win.get_x_size() / self._gui_scale) - 1054) // 2, y=(Globals.base.win.get_y_size() / self._gui_scale) - 118 - 40, parent=self._fullscreen_node) Sequence( python_warning.color_scale_interval(0.7, Vec4(0.3, 1, 1, 0.7), blendType="easeOut"), python_warning.color_scale_interval(0.7, Vec4(1, 1, 1, 1.0), blendType="easeOut"), ).loop() # Keybinding hints self._keybinding_instructions = Sprite( image="/$$rp/data/gui/keybindings.png", x=30, y=Globals.base.win.get_y_size() // self._gui_scale - 510.0, parent=self._fullscreen_node, any_filter=False)
def create_components(self): """ Creates the gui components """ self.debugger_width = 460 self.debugger_visible = False self.debugger_interval = None self.create_stats() self.create_hints() self.pipeline_logo = Sprite( image="/$$rp/data/gui/pipeline_logo_text.png", x=30, y=30, parent=self.fullscreen_node) if self.advanced_info: self.exposure_node = self.fullscreen_node.attach_new_node("ExposureWidget") self.exposure_widget = ExposureWidget(self.pipeline, self.exposure_node) self.fps_node = self.fullscreen_node.attach_new_node("FPSChart") self.fps_node.set_pos(Vec3(21, 1, -108 - 40)) self.fps_widget = FPSChart(self.pipeline, self.fps_node) self.pixel_widget = PixelInspector(self.pipeline) self.buffer_viewer = BufferViewer(self.pipeline, self.fullscreen_node) self.pipe_viewer = PipeViewer(self.pipeline, self.fullscreen_node) self.rm_selector = RenderModeSelector(self.pipeline, self.fullscreen_node) self.error_msg_handler = ErrorMessageDisplay() self.handle_window_resize()
def _create_components(self): """ Internal method to init the widgets components """ # Create the buffer which stores the last FPS values self._storage_buffer = Image.create_buffer("FPSValues", 250, "R16") self._storage_buffer.set_clear_color(Vec4(0)) self._storage_buffer.clear_image() self._store_index = PTAInt.empty_array(1) self._store_index[0] = 0 self._current_ftime = PTAFloat.empty_array(1) self._current_ftime[0] = 16.0 self._chart_ms_max = PTAFloat.empty_array(1) self._chart_ms_max[0] = 40 # Create the texture where the gui component is rendered inside self._display_tex = Image.create_2d("FPSChartRender", 250, 120, "RGBA8") self._display_tex.set_clear_color(Vec4(0)) self._display_tex.clear_image() self._display_img = Sprite(image=self._display_tex, parent=self._node, w=250, h=120, x=10, y=10) # Defer the further loading Globals.base.taskMgr.doMethodLater(0.3, self._late_init, "FPSChartInit")
def _create_topbar(self): """ Creates the topbar """ self._pipeline_logo = Sprite( image="/$$rp/data/gui/pipeline_logo_text.png", x=30, y=30, parent=self._fullscreen_node)
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 create(self): """ Creates the gui components """ screen_w, screen_h = Globals.base.win.get_x_size(), Globals.base.win.get_y_size() self.fullscreen_node = Globals.base.pixel2dp.attach_new_node("LoadingScreen") self.fullscreen_node.set_bin("fixed", 10) self.fullscreen_node.set_depth_test(False) scale_w = screen_w / 1920.0 scale_h = screen_h / 1080.0 scale = max(scale_w, scale_h) self.fullscreen_bg = Sprite( image="/$$rp/data/gui/loading_screen_bg.txo", x=(screen_w-1920.0*scale)//2, y=(screen_h-1080.0*scale)//2, w=int(1920 * scale), h=int(1080 * scale), parent=self.fullscreen_node, near_filter=False) for _ in range(2): Globals.base.graphicsEngine.render_frame()
def create(self): """ Creates the gui components """ screen_w, screen_h = Globals.native_resolution.x, Globals.native_resolution.y self.fullscreen_node = Globals.base.pixel2dp.attach_new_node( "LoadingScreen") self.fullscreen_node.set_bin("fixed", 10) self.fullscreen_node.set_depth_test(False) scale_w = screen_w / 1920.0 scale_h = screen_h / 1080.0 scale = max(scale_w, scale_h) self.fullscreen_bg = Sprite(image=self.image_source, x=(screen_w - 1920.0 * scale) // 2, y=(screen_h - 1080.0 * scale) // 2, w=int(1920 * scale), h=int(1080 * scale), parent=self.fullscreen_node, near_filter=False) for _ in range(2): Globals.base.graphicsEngine.render_frame()
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()