示例#1
0
    def renderQuadInto(self,
                       mul=1,
                       div=1,
                       align=1,
                       depthtex=None,
                       colortex=None,
                       auxtex0=None,
                       auxtex1=None):
        """ Creates an offscreen buffer for an intermediate
        computation. Installs a quad into the buffer.  Returns
        the fullscreen quad.  The size of the buffer is initially
        equal to the size of the main window.  The parameters 'mul',
        'div', and 'align' can be used to adjust that size. """

        texgroup = (depthtex, colortex, auxtex0, auxtex1)

        winx, winy = self.getScaledSize(mul, div, align)

        depthbits = bool(depthtex != None)

        buffer = self.createBuffer("filter-stage", winx, winy, texgroup,
                                   depthbits)

        if (buffer == None):
            return None

        cm = CardMaker("filter-stage-quad")
        cm.setFrameFullscreenQuad()
        quad = NodePath(cm.generate())
        quad.setDepthTest(0)
        quad.setDepthWrite(0)
        quad.setColor(Vec4(1, 0.5, 0.5, 1))

        quadcamnode = Camera("filter-quad-cam")
        lens = OrthographicLens()
        lens.setFilmSize(2, 2)
        lens.setFilmOffset(0, 0)
        lens.setNearFar(-1000, 1000)
        quadcamnode.setLens(lens)
        quadcam = quad.attachNewNode(quadcamnode)

        buffer.getDisplayRegion(0).setCamera(quadcam)
        buffer.getDisplayRegion(0).setActive(1)

        self.buffers.append(buffer)
        self.sizes.append((mul, div, align))

        return quad
示例#2
0
    def renderQuadInto(self, mul=1, div=1, align=1, depthtex=None, colortex=None, auxtex0=None, auxtex1=None):

        """ Creates an offscreen buffer for an intermediate
        computation. Installs a quad into the buffer.  Returns
        the fullscreen quad.  The size of the buffer is initially
        equal to the size of the main window.  The parameters 'mul',
        'div', and 'align' can be used to adjust that size. """

        texgroup = (depthtex, colortex, auxtex0, auxtex1)

        winx, winy = self.getScaledSize(mul, div, align)

        depthbits = bool(depthtex != None)

        buffer = self.createBuffer("filter-stage", winx, winy, texgroup, depthbits)

        if buffer == None:
            return None

        cm = CardMaker("filter-stage-quad")
        cm.setFrameFullscreenQuad()
        quad = NodePath(cm.generate())
        quad.setDepthTest(0)
        quad.setDepthWrite(0)
        quad.setColor(Vec4(1, 0.5, 0.5, 1))

        quadcamnode = Camera("filter-quad-cam")
        lens = OrthographicLens()
        lens.setFilmSize(2, 2)
        lens.setFilmOffset(0, 0)
        lens.setNearFar(-1000, 1000)
        quadcamnode.setLens(lens)
        quadcam = quad.attachNewNode(quadcamnode)

        buffer.getDisplayRegion(0).setCamera(quadcam)
        buffer.getDisplayRegion(0).setActive(1)

        self.buffers.append(buffer)
        self.sizes.append((mul, div, align))

        return quad
示例#3
0
class MotionTrails(DirectObject):
    def __init__(self):
        
        # create a texture into which we can copy the main window.

        self.tex = Texture()
        self.tex.setMinfilter(Texture.FTLinear)
        base.win.addRenderTexture(self.tex, GraphicsOutput.RTMTriggeredCopyTexture)
        
        # Create another 2D camera. Tell it to render before the main camera.

        self.backcam = base.makeCamera2d(base.win, sort=-10)
        self.background = NodePath("background")
        self.backcam.reparentTo(self.background)
        self.background.setDepthTest(0)
        self.background.setDepthWrite(0)
        self.backcam.node().getDisplayRegion(0).setClearDepthActive(0)

        # Obtain two texture cards. One renders before the dragon, the other after.
        self.bcard = base.win.getTextureCard()
        self.bcard.reparentTo(self.background)
        self.bcard.setTransparency(1)
        self.fcard = base.win.getTextureCard()
        self.fcard.reparentTo(render2d)
        self.fcard.setTransparency(1)

        # Initialize one of the nice effects.
        self.chooseEffectGhost()
        
        # Add the task that initiates the screenshots.
        taskMgr.add(self.takeSnapShot, "takeSnapShot")

        # Create some black squares on top of which we will
        # place the instructions.
        blackmaker = CardMaker("blackmaker")
        blackmaker.setColor(0,0,0,1)
        blackmaker.setFrame(-1.00, -0.50, 0.65, 1.00)
        instcard = NodePath(blackmaker.generate())
        instcard.reparentTo(render2d)
        blackmaker.setFrame(-0.5, 0.5, -1.00, -0.85)
        titlecard = NodePath(blackmaker.generate())
        titlecard.reparentTo(render2d)

        # Panda does its best to hide the differences between DirectX and
        # OpenGL.  But there are a few differences that it cannot hide.
        # One such difference is that when OpenGL copies from a
        # visible window to a texture, it gets it right-side-up.  When
        # DirectX does it, it gets it upside-down.  There is nothing panda
        # can do to compensate except to expose a flag and let the 
        # application programmer deal with it.  You should only do this
        # in the rare event that you're copying from a visible window
        # to a texture.

        if (base.win.getGsg().getCopyTextureInverted()):
            print "Copy texture is inverted."
            self.bcard.setScale(1,1,-1)
            self.fcard.setScale(1,1,-1)

        # Put up the instructions
        title = OnscreenText(text="Panda3D: Tutorial - Motion Trails",
                             style=1, fg=(1,1,1,1), font = font,
                             pos=(0,-0.95), scale = .07)
        
        instr0 = addInstructions(0.95, "Press ESC to exit")
        instr1 = addInstructions(0.90, "Press 1: Ghost effect")
        instr2 = addInstructions(0.85, "Press 2: PaintBrush effect")
        instr3 = addInstructions(0.80, "Press 3: Double Vision effect")
        instr4 = addInstructions(0.75, "Press 4: Wings of Blue effect")
        instr5 = addInstructions(0.70, "Press 5: Whirlpool effect")
        
        # enable the key events
        self.accept("escape", sys.exit, [0])
        self.accept("1", self.chooseEffectGhost)
        self.accept("2", self.chooseEffectPaintBrush)
        self.accept("3", self.chooseEffectDoubleVision)
        self.accept("4", self.chooseEffectWingsOfBlue)
        self.accept("5", self.chooseEffectWhirlpool)
    
    def takeSnapShot(self, task):
        if (task.time > self.nextclick):
            self.nextclick += 1.0 / self.clickrate
            if (self.nextclick < task.time):
                self.nextclick = task.time
            base.win.triggerCopy()
        return Task.cont

    def chooseEffectGhost(self):
        base.setBackgroundColor(0,0,0,1)
        self.bcard.hide()
        self.fcard.show()
        self.fcard.setColor(1.0,1.0,1.0,0.99)
        self.fcard.setScale(1.00)
        self.fcard.setPos(0,0,0)
        self.fcard.setR(0)
        self.clickrate = 30
        self.nextclick = 0
        
    def chooseEffectPaintBrush(self):
        base.setBackgroundColor(0,0,0,1)
        self.bcard.show()
        self.fcard.hide()
        self.bcard.setColor(1,1,1,1)
        self.bcard.setScale(1.0)
        self.bcard.setPos(0,0,0)
        self.bcard.setR(0)
        self.clickrate = 10000
        self.nextclick = 0

    def chooseEffectDoubleVision(self):
        base.setBackgroundColor(0,0,0,1)
        self.bcard.show()
        self.bcard.setColor(1,1,1,1)
        self.bcard.setScale(1.0)
        self.bcard.setPos(-0.05,0,0)
        self.bcard.setR(0)
        self.fcard.show()
        self.fcard.setColor(1,1,1,0.60)
        self.fcard.setScale(1.0)
        self.fcard.setPos(0.05,0,0)
        self.fcard.setR(0)
        self.clickrate = 10000
        self.nextclick = 0

    def chooseEffectWingsOfBlue(self):
        base.setBackgroundColor(0,0,0,1)
        self.fcard.hide()
        self.bcard.show()
        self.bcard.setColor(1.0,0.90,1.0,254.0/255.0)
        self.bcard.setScale(1.1,0,0.95)
        self.bcard.setPos(0,0,0.05)
        self.bcard.setR(0)
        self.clickrate = 30
        self.nextclick = 0

    def chooseEffectWhirlpool(self):
        base.setBackgroundColor(0,0,0,1)
        self.bcard.show()
        self.fcard.hide()
        self.bcard.setColor(1,1,1,1)
        self.bcard.setScale(0.999)
        self.bcard.setPos(0,0,0)
        self.bcard.setR(1)
        self.clickrate = 10000
        self.nextclick = 0
示例#4
0
    def renderSceneInto(self,
                        depthtex=None,
                        colortex=None,
                        auxtex=None,
                        auxbits=0,
                        textures=None):
        """ Causes the scene to be rendered into the supplied textures
        instead of into the original window.  Puts a fullscreen quad
        into the original window to show the render-to-texture results.
        Returns the quad.  Normally, the caller would then apply a
        shader to the quad.

        To elaborate on how this all works:

        * An offscreen buffer is created.  It is set up to mimic
          the original display region - it is the same size,
          uses the same clear colors, and contains a DisplayRegion
          that uses the original camera.

        * A fullscreen quad and an orthographic camera to render
          that quad are both created.  The original camera is
          removed from the original window, and in its place, the
          orthographic quad-camera is installed.

        * The fullscreen quad is textured with the data from the
          offscreen buffer.  A shader is applied that tints the
          results pink.

        * Automatic shader generation NOT enabled.
          If you have a filter that depends on a render target from
          the auto-shader, you either need to set an auto-shader
          attrib on the main camera or scene, or, you need to provide
          these outputs in your own shader.

        * All clears are disabled on the original display region.
          If the display region fills the whole window, then clears
          are disabled on the original window as well.  It is
          assumed that rendering the full-screen quad eliminates
          the need to do clears.

        Hence, the original window which used to contain the actual
        scene, now contains a pink-tinted quad with a texture of the
        scene.  It is assumed that the user will replace the shader
        on the quad with a more interesting filter. """

        if (textures):
            colortex = textures.get("color", None)
            depthtex = textures.get("depth", None)
            auxtex = textures.get("aux", None)

        if (colortex == None):
            colortex = Texture("filter-base-color")
            colortex.setWrapU(Texture.WMClamp)
            colortex.setWrapV(Texture.WMClamp)

        texgroup = (depthtex, colortex, auxtex, None)

        # Choose the size of the offscreen buffer.

        (winx, winy) = self.getScaledSize(1, 1, 1)
        buffer = self.createBuffer("filter-base", winx, winy, texgroup)

        if (buffer == None):
            return None

        cm = CardMaker("filter-base-quad")
        cm.setFrameFullscreenQuad()
        quad = NodePath(cm.generate())
        quad.setDepthTest(0)
        quad.setDepthWrite(0)
        quad.setTexture(colortex)
        quad.setColor(Vec4(1, 0.5, 0.5, 1))

        cs = NodePath("dummy")
        cs.setState(self.camstate)
        # Do we really need to turn on the Shader Generator?
        #cs.setShaderAuto()
        if (auxbits):
            cs.setAttrib(AuxBitplaneAttrib.make(auxbits))
        self.camera.node().setInitialState(cs.getState())

        quadcamnode = Camera("filter-quad-cam")
        lens = OrthographicLens()
        lens.setFilmSize(2, 2)
        lens.setFilmOffset(0, 0)
        lens.setNearFar(-1000, 1000)
        quadcamnode.setLens(lens)
        quadcam = quad.attachNewNode(quadcamnode)

        self.region.setCamera(quadcam)

        dr = buffer.getDisplayRegion(0)
        self.setStackedClears(dr, self.rclears, self.wclears)
        if (auxtex):
            dr.setClearActive(GraphicsOutput.RTPAuxRgba0, 1)
            dr.setClearValue(GraphicsOutput.RTPAuxRgba0,
                             Vec4(0.5, 0.5, 1.0, 0.0))
        self.region.disableClears()
        if (self.isFullscreen()):
            self.win.disableClears()
        dr.setCamera(self.camera)
        dr.setActive(1)

        self.buffers.append(buffer)
        self.sizes.append((1, 1, 1))

        return quad
示例#5
0
    def renderSceneInto(self, depthtex=None, colortex=None, auxtex=None, auxbits=0, textures=None):

        """ Causes the scene to be rendered into the supplied textures
        instead of into the original window.  Puts a fullscreen quad
        into the original window to show the render-to-texture results.
        Returns the quad.  Normally, the caller would then apply a
        shader to the quad.

        To elaborate on how this all works:

        * An offscreen buffer is created.  It is set up to mimic
          the original display region - it is the same size,
          uses the same clear colors, and contains a DisplayRegion
          that uses the original camera.

        * A fullscreen quad and an orthographic camera to render
          that quad are both created.  The original camera is
          removed from the original window, and in its place, the
          orthographic quad-camera is installed.

        * The fullscreen quad is textured with the data from the
          offscreen buffer.  A shader is applied that tints the
          results pink.

        * Automatic shader generation NOT enabled.
          If you have a filter that depends on a render target from
          the auto-shader, you either need to set an auto-shader
          attrib on the main camera or scene, or, you need to provide
          these outputs in your own shader.

        * All clears are disabled on the original display region.
          If the display region fills the whole window, then clears
          are disabled on the original window as well.  It is
          assumed that rendering the full-screen quad eliminates
          the need to do clears.

        Hence, the original window which used to contain the actual
        scene, now contains a pink-tinted quad with a texture of the
        scene.  It is assumed that the user will replace the shader
        on the quad with a more interesting filter. """

        if textures:
            colortex = textures.get("color", None)
            depthtex = textures.get("depth", None)
            auxtex = textures.get("aux", None)

        if colortex == None:
            colortex = Texture("filter-base-color")
            colortex.setWrapU(Texture.WMClamp)
            colortex.setWrapV(Texture.WMClamp)

        texgroup = (depthtex, colortex, auxtex, None)

        # Choose the size of the offscreen buffer.

        (winx, winy) = self.getScaledSize(1, 1, 1)
        buffer = self.createBuffer("filter-base", winx, winy, texgroup)

        if buffer == None:
            return None

        cm = CardMaker("filter-base-quad")
        cm.setFrameFullscreenQuad()
        quad = NodePath(cm.generate())
        quad.setDepthTest(0)
        quad.setDepthWrite(0)
        quad.setTexture(colortex)
        quad.setColor(Vec4(1, 0.5, 0.5, 1))

        cs = NodePath("dummy")
        cs.setState(self.camstate)
        # Do we really need to turn on the Shader Generator?
        # cs.setShaderAuto()
        if auxbits:
            cs.setAttrib(AuxBitplaneAttrib.make(auxbits))
        self.camera.node().setInitialState(cs.getState())

        quadcamnode = Camera("filter-quad-cam")
        lens = OrthographicLens()
        lens.setFilmSize(2, 2)
        lens.setFilmOffset(0, 0)
        lens.setNearFar(-1000, 1000)
        quadcamnode.setLens(lens)
        quadcam = quad.attachNewNode(quadcamnode)

        self.region.setCamera(quadcam)

        dr = buffer.getDisplayRegion(0)
        self.setStackedClears(dr, self.rclears, self.wclears)
        if auxtex:
            dr.setClearActive(GraphicsOutput.RTPAuxRgba0, 1)
            dr.setClearValue(GraphicsOutput.RTPAuxRgba0, Vec4(0.5, 0.5, 1.0, 0.0))
        self.region.disableClears()
        if self.isFullscreen():
            self.win.disableClears()
        dr.setCamera(self.camera)
        dr.setActive(1)

        self.buffers.append(buffer)
        self.sizes.append((1, 1, 1))

        return quad
示例#6
0
class MotionTrails(DirectObject):
    def __init__(self):

        # create a texture into which we can copy the main window.

        self.tex = Texture()
        self.tex.setMinfilter(Texture.FTLinear)
        base.win.addRenderTexture(self.tex,
                                  GraphicsOutput.RTMTriggeredCopyTexture)

        # Create another 2D camera. Tell it to render before the main camera.

        self.backcam = base.makeCamera2d(base.win, sort=-10)
        self.background = NodePath("background")
        self.backcam.reparentTo(self.background)
        self.background.setDepthTest(0)
        self.background.setDepthWrite(0)
        self.backcam.node().getDisplayRegion(0).setClearDepthActive(0)

        # Obtain two texture cards. One renders before the dragon, the other after.
        self.bcard = base.win.getTextureCard()
        self.bcard.reparentTo(self.background)
        self.bcard.setTransparency(1)
        self.fcard = base.win.getTextureCard()
        self.fcard.reparentTo(render2d)
        self.fcard.setTransparency(1)

        # Initialize one of the nice effects.
        self.chooseEffectGhost()

        # Add the task that initiates the screenshots.
        taskMgr.add(self.takeSnapShot, "takeSnapShot")

        # Create some black squares on top of which we will
        # place the instructions.
        blackmaker = CardMaker("blackmaker")
        blackmaker.setColor(0, 0, 0, 1)
        blackmaker.setFrame(-1.00, -0.50, 0.65, 1.00)
        instcard = NodePath(blackmaker.generate())
        instcard.reparentTo(render2d)
        blackmaker.setFrame(-0.5, 0.5, -1.00, -0.85)
        titlecard = NodePath(blackmaker.generate())
        titlecard.reparentTo(render2d)

        # Panda does its best to hide the differences between DirectX and
        # OpenGL.  But there are a few differences that it cannot hide.
        # One such difference is that when OpenGL copies from a
        # visible window to a texture, it gets it right-side-up.  When
        # DirectX does it, it gets it upside-down.  There is nothing panda
        # can do to compensate except to expose a flag and let the
        # application programmer deal with it.  You should only do this
        # in the rare event that you're copying from a visible window
        # to a texture.

        if (base.win.getGsg().getCopyTextureInverted()):
            print "Copy texture is inverted."
            self.bcard.setScale(1, 1, -1)
            self.fcard.setScale(1, 1, -1)

        # Put up the instructions
        title = OnscreenText(text="Panda3D: Tutorial - Motion Trails",
                             style=1,
                             fg=(1, 1, 1, 1),
                             font=font,
                             pos=(0, -0.95),
                             scale=.07)

        instr0 = addInstructions(0.95, "Press ESC to exit")
        instr1 = addInstructions(0.90, "Press 1: Ghost effect")
        instr2 = addInstructions(0.85, "Press 2: PaintBrush effect")
        instr3 = addInstructions(0.80, "Press 3: Double Vision effect")
        instr4 = addInstructions(0.75, "Press 4: Wings of Blue effect")
        instr5 = addInstructions(0.70, "Press 5: Whirlpool effect")

        # enable the key events
        self.accept("escape", sys.exit, [0])
        self.accept("1", self.chooseEffectGhost)
        self.accept("2", self.chooseEffectPaintBrush)
        self.accept("3", self.chooseEffectDoubleVision)
        self.accept("4", self.chooseEffectWingsOfBlue)
        self.accept("5", self.chooseEffectWhirlpool)

    def takeSnapShot(self, task):
        if (task.time > self.nextclick):
            self.nextclick += 1.0 / self.clickrate
            if (self.nextclick < task.time):
                self.nextclick = task.time
            base.win.triggerCopy()
        return Task.cont

    def chooseEffectGhost(self):
        base.setBackgroundColor(0, 0, 0, 1)
        self.bcard.hide()
        self.fcard.show()
        self.fcard.setColor(1.0, 1.0, 1.0, 0.99)
        self.fcard.setScale(1.00)
        self.fcard.setPos(0, 0, 0)
        self.fcard.setR(0)
        self.clickrate = 30
        self.nextclick = 0

    def chooseEffectPaintBrush(self):
        base.setBackgroundColor(0, 0, 0, 1)
        self.bcard.show()
        self.fcard.hide()
        self.bcard.setColor(1, 1, 1, 1)
        self.bcard.setScale(1.0)
        self.bcard.setPos(0, 0, 0)
        self.bcard.setR(0)
        self.clickrate = 10000
        self.nextclick = 0

    def chooseEffectDoubleVision(self):
        base.setBackgroundColor(0, 0, 0, 1)
        self.bcard.show()
        self.bcard.setColor(1, 1, 1, 1)
        self.bcard.setScale(1.0)
        self.bcard.setPos(-0.05, 0, 0)
        self.bcard.setR(0)
        self.fcard.show()
        self.fcard.setColor(1, 1, 1, 0.60)
        self.fcard.setScale(1.0)
        self.fcard.setPos(0.05, 0, 0)
        self.fcard.setR(0)
        self.clickrate = 10000
        self.nextclick = 0

    def chooseEffectWingsOfBlue(self):
        base.setBackgroundColor(0, 0, 0, 1)
        self.fcard.hide()
        self.bcard.show()
        self.bcard.setColor(1.0, 0.90, 1.0, 254.0 / 255.0)
        self.bcard.setScale(1.1, 0, 0.95)
        self.bcard.setPos(0, 0, 0.05)
        self.bcard.setR(0)
        self.clickrate = 30
        self.nextclick = 0

    def chooseEffectWhirlpool(self):
        base.setBackgroundColor(0, 0, 0, 1)
        self.bcard.show()
        self.fcard.hide()
        self.bcard.setColor(1, 1, 1, 1)
        self.bcard.setScale(0.999)
        self.bcard.setPos(0, 0, 0)
        self.bcard.setR(1)
        self.clickrate = 10000
        self.nextclick = 0