예제 #1
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
예제 #2
0
class ExposureWidget(DebugObject):

    """ Widget to show the current exposure """

    def __init__(self, pipeline, parent):
        """ Inits the widget """
        DebugObject.__init__(self)
        self._pipeline = pipeline
        self._parent = parent
        self._node = self._parent.attach_new_node("ExposureWidgetNode")
        self._create_components()


    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, Texture.T_unsigned_byte, Texture.F_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 = BetterOnscreenImage(
            image=self._storage_tex, parent=self._node, w=140, h=20, x=20, y=50)

        self._display_txt = BetterOnscreenText(
            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 initialized, this extracts the
        exposure texture from the stage manager """

        stage_mgr = self._pipeline.stage_mgr

        if not stage_mgr.has_pipe("Exposure"):
            self.debug("Disabling exposure widget, could not find the exposure data.")
            self._node.remove_node()
            return

        self._node.show()

        exposure_tex = stage_mgr.get_pipe("Exposure")
        self._cshader = Shader.load_compute(Shader.SL_GLSL, "Shader/GUI/VisualizeExposure.compute.glsl")
        self._cshader_np.set_shader(self._cshader)
        self._cshader_np.set_shader_input("DestTex", self._storage_tex)
        self._cshader_np.set_shader_input("ExposureTex", exposure_tex)
예제 #3
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")
예제 #4
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")
예제 #5
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
예제 #6
0
    def enable(self):
        if not self.isSupported():
            # HDR/auto exposure is implemented using compute
            # shaders, which are only supported by more modern
            # graphics cards and requires at least OpenGL 4.3.
            return

        self.sceneTex = Texture('hdrSceneTex')
        self.sceneTex.setup2dTexture(self.Size, self.Size, Texture.TFloat, Texture.FRgba32)
        self.sceneTex.setWrapU(SamplerState.WMClamp)
        self.sceneTex.setWrapV(SamplerState.WMClamp)
        self.sceneTex.clearImage()
        
        self.__setupSceneQuad()

        # Build luminance histogram bucket ranges.
        self.ptaBucketRange = PTALVecBase2f.emptyArray(self.NumBuckets)
        for i in xrange(self.NumBuckets):
            # Use even distribution
            bmin = float(i) / float(self.NumBuckets)
            bmax = float(i + 1) / float(self.NumBuckets)

            # Use a distribution with slightly more bins in the low range.
            if bmin > 0.0:
                bmin = math.pow(bmin, 1.5)
            if bmax > 0.0:
                bmax = math.pow(bmax, 1.5)

            self.ptaBucketRange.setElement(i, Vec2(bmin, bmax))

        self.histogramTex = Texture('histogram')
        self.histogramTex.setup1dTexture(self.NumBuckets, Texture.TInt, Texture.FR32i)
        self.histogramTex.setClearColor(Vec4(0))
        self.histogramTex.clearImage()
        self.histogramCompute = base.computeRoot.attachNewNode(ComputeNode('histogramCompute'))
        self.histogramCompute.node().addDispatch(self.Size / 8, self.Size / 8, self.Size / 16)
        self.histogramCompute.setShader(Shader.loadCompute(Shader.SLGLSL, "phase_14/models/shaders/build_histogram.compute.glsl"), 1)
        self.histogramCompute.setShaderInput("scene_texture", self.sceneTex)
        self.histogramCompute.setShaderInput("histogram_texture", self.histogramTex)
        self.histogramCompute.setShaderInput("bucketrange", self.ptaBucketRange)
        self.histogramCompute.setBin("fixed", 0)

        self.exposureTex = Texture('exposure')
        self.exposureTex.setup1dTexture(1, Texture.TFloat, Texture.FR16)
        self.exposureTex.setClearColor(Vec4(0.0))
        self.exposureTex.clearImage()
        self.exposureCompute = base.computeRoot.attachNewNode(ComputeNode('exposureCompute'))
        self.exposureCompute.node().addDispatch(1, 1, 1)
        self.exposureCompute.setShader(Shader.loadCompute(Shader.SLGLSL, "phase_14/models/shaders/calc_luminance.compute.glsl"), 1)
        self.exposureCompute.setShaderInput("histogram_texture", self.histogramTex)
        self.exposureCompute.setShaderInput("avg_lum_texture", self.exposureTex)
        self.exposureCompute.setShaderInput("bucketrange", self.ptaBucketRange)
        self.exposureCompute.setShaderInput("exposure_minmax", Vec2(1.0, 2.0))
        self.exposureCompute.setShaderInput("adaption_rate_brightdark", Vec2(0.6, 0.6))
        self.exposureCompute.setShaderInput("exposure_scale", base.config.GetFloat("hdr-tonemapscale", 1.75))
        self.exposureCompute.setShaderInput("config_minAvgLum", base.config.GetFloat("hdr-min-avglum", 3.0))
        self.exposureCompute.setShaderInput("config_perctBrightPixels", base.config.GetFloat("hdr-percent-bright-pixels", 2.0))
        self.exposureCompute.setShaderInput("config_perctTarget", base.config.GetFloat("hdr-percent-target", 60.0))
        self.exposureCompute.setBin("fixed", 1)
        
        base.filters.setExposure(self.exposureTex)

        taskMgr.add(self.__update, "hdrUpdate", sort = -10000000)

        if base.config.GetBool("hdr-debug-histogram", False):
            self.debugTex = Texture('histogramDebugTex')
            self.debugTex.setup2dTexture(self.NumBuckets, 1, Texture.TFloat, Texture.FRgba32)
            self.debugTex.setMagfilter(SamplerState.FTNearest)
            self.debugTex.setClearColor(Vec4(0.3, 0.3, 0.5, 1.0))
            self.debugTex.clearImage()
            self.debugCompute = base.computeRoot.attachNewNode(ComputeNode('debugHistogramCompute'))
            self.debugCompute.node().addDispatch(1, 1, 1)
            self.debugCompute.setShader(Shader.loadCompute(Shader.SLGLSL, "phase_14/models/shaders/debug_histogram.compute.glsl"), 1)
            self.debugCompute.setShaderInput("histogram_texture", self.histogramTex)
            self.debugCompute.setShaderInput("debug_texture", self.debugTex)
            self.debugCompute.setBin("fixed", 2)
            self.debugImg = OnscreenImage(image = self.debugTex, scale = 0.3, pos = (-0.6, -0.7, -0.7))
예제 #7
0
class FPSChart(RPObject):
    """ Widget to show the FPS as a chart """
    def __init__(self, pipeline, parent):
        """ Inits the widget """
        RPObject.__init__(self)
        self._pipeline = pipeline
        self._parent = parent
        self._node = self._parent.attach_new_node("FPSChartNode")
        self._create_components()

    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 _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_inputs(DestTex=self._display_tex,
                                           FPSValues=self._storage_buffer,
                                           index=self._store_index,
                                           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_inputs(
            DestTex=self._storage_buffer,
            index=self._store_index,
            currentData=self._current_ftime)

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

        return task.done

    def _update(self, task):
        """ Updates the widget """
        self._store_index[0] = (self._store_index[0] + 1) % 250
        self._current_ftime[0] = Globals.clock.get_dt() * 1000.0

        avg_fps = Globals.clock.get_average_frame_rate()
        if avg_fps > 122:
            self._chart_ms_max[0] = 10.0
        elif avg_fps > 62:
            self._chart_ms_max[0] = 20.0
        elif avg_fps > 32:
            self._chart_ms_max[0] = 40.0
        elif avg_fps > 15:
            self._chart_ms_max[0] = 70.0
        else:
            self._chart_ms_max[0] = 200.0

        self._display_txt.set_text(str(int(self._chart_ms_max[0])) + " ms")

        return task.cont
예제 #8
0
class ExposureWidget(RPObject):
    """ Widget to show the current exposure """
    def __init__(self, pipeline, parent):
        """ Inits the widget """
        RPObject.__init__(self)
        self._pipeline = pipeline
        self._parent = parent
        self._node = self._parent.attach_new_node("ExposureWidgetNode")
        self._create_components()

    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 initialized, this extracts the
        exposure texture from the stage manager """
        stage_mgr = self._pipeline.stage_mgr

        if "Exposure" not in stage_mgr.pipes:
            self.debug(
                "Disabling exposure widget, could not find the exposure data.")
            self._node.remove_node()
            return

        self._node.show()

        exposure_tex = stage_mgr.pipes["Exposure"]
        self._cshader = RPLoader.load_shader(
            "/$$rp/shader/visualize_exposure.compute.glsl")
        self._cshader_np.set_shader(self._cshader)
        self._cshader_np.set_shader_input("DestTex", self._storage_tex)
        self._cshader_np.set_shader_input("ExposureTex", exposure_tex)

        return task.done
예제 #9
0
class FPSChart(RPObject):

    """ Widget to show the FPS as a chart """

    def __init__(self, pipeline, parent):
        """ Inits the widget """
        RPObject.__init__(self)
        self._pipeline = pipeline
        self._parent = parent
        self._node = self._parent.attach_new_node("FPSChartNode")
        self._create_components()

    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 _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 _update(self, task):
        """ Updates the widget """
        self._store_index[0] = (self._store_index[0] + 1) % 250
        self._current_ftime[0] = Globals.clock.get_dt() * 1000.0


        avg_fps = Globals.clock.get_average_frame_rate()
        if avg_fps > 122:
            self._chart_ms_max[0] = 10.0
        elif avg_fps > 62:
            self._chart_ms_max[0] = 20.0
        elif avg_fps > 32:
            self._chart_ms_max[0] = 40.0
        elif avg_fps > 15:
            self._chart_ms_max[0] = 70.0
        else:
            self._chart_ms_max[0] = 200.0

        self._display_txt.set_text(str(int(self._chart_ms_max[0])) + " ms")

        return task.cont