tut-firefflies+tut_movieplayer [Solved]

i want to combine tut-firefflies+tut_movieplayer,
so that on the start-screen you can see fireflies and if you press “p” the movie should start.

-> i combined the two tutorials but i get "

" as an error-message…
-> without the parts between “movie:” - “/movie:” everything is working fine. combination doesn’t work:( what is wrong?? thx

#Author: Josh Yelon
#Date: 7/11/2005
#
# See the associated HTML file for an explanation.

movie:

from panda3d.core import *
# Tell Panda3D to use OpenAL, not FMOD
loadPrcFileData("", "audio-library-name p3openal_audio")
from direct.showbase.DirectObject import DirectObject
from direct.gui.OnscreenText import OnscreenText
import direct.directbase.DirectStart

# The name of the media file.
MEDIAFILE="PandaSneezes.avi"

/movie

import direct.directbase.DirectStart
from panda3d.core import FrameBufferProperties, WindowProperties
from panda3d.core import GraphicsPipe,GraphicsOutput
from panda3d.core import Filename,Texture,Shader
from panda3d.core import RenderState, CardMaker
from panda3d.core import PandaNode,TextNode,NodePath
from panda3d.core import RenderAttrib,AlphaTestAttrib,ColorBlendAttrib
from panda3d.core import CullFaceAttrib,DepthTestAttrib,DepthWriteAttrib
from panda3d.core import Point3,Vec3,Vec4,BitMask32
from direct.gui.OnscreenText import OnscreenText
from direct.showbase.DirectObject import DirectObject
from direct.interval.MetaInterval import Sequence
from direct.task.Task import Task
from direct.actor.Actor import Actor
import sys,os,random

# Function to put instructions on the screen.
def addInstructions(pos, msg):
    return OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-21.3, pos), align=TextNode.ALeft, scale = .05)

# Function to put title on the screen.
def addTitle(text):
    return OnscreenText(text=text, style=1, fg=(1,1,1,1),
                        pos=(12.3,-0.95), align=TextNode.ARight, scale = .07)


class FireflyDemo(DirectObject):
    def __init__(self):
        self.n=1
        # Preliminary capabilities check.

        if (base.win.getGsg().getSupportsBasicShaders()==0):
            self.t=addTitle("Firefly Demo: Video driver reports that shaders are not supported.")
            return
        if (base.win.getGsg().getSupportsDepthTexture()==0):
            self.t=addTitle("Firefly Demo: Video driver reports that depth textures are not supported.")
            return
        
        # This algorithm uses two offscreen buffers, one of which has
        # an auxiliary bitplane, and the offscreen buffers share a single
        # depth buffer.  This is a heck of a complicated buffer setup.

        self.modelbuffer = self.makeFBO("model buffer",1)
        self.lightbuffer = self.makeFBO("light buffer",0)
        
        # Creation of a high-powered buffer can fail, if the graphics card
        # doesn't support the necessary OpenGL extensions.

        if (self.modelbuffer == None) or (self.lightbuffer == None):
            self.t=addTitle("Toon Shader: Video driver does not support multiple render targets")
            return

        # Create four render textures: depth, normal, albedo, and final.
        # attach them to the various bitplanes of the offscreen buffers.

        self.texDepth = Texture()
        self.texDepth.setFormat(Texture.FDepthStencil)
        self.texAlbedo = Texture()
        self.texNormal = Texture()
        self.texFinal = Texture()

        self.modelbuffer.addRenderTexture(self.texDepth,  GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPDepthStencil)
        self.modelbuffer.addRenderTexture(self.texAlbedo, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPColor)
        self.modelbuffer.addRenderTexture(self.texNormal, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPAuxRgba0)

        self.lightbuffer.addRenderTexture(self.texFinal,  GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPColor)

        # Set the near and far clipping planes.
        
        base.cam.node().getLens().setNear(50.0)
        base.cam.node().getLens().setFar(500.0)
        lens = base.cam.node().getLens()

        # This algorithm uses three cameras: one to render the models into the
        # model buffer, one to render the lights into the light buffer, and
        # one to render "plain" stuff (non-deferred shaded) stuff into the light
        # buffer.  Each camera has a bitmask to identify it.

        self.modelMask = 1
        self.lightMask = 2
        self.plainMask = 4
        
        self.modelcam=base.makeCamera(self.modelbuffer, lens=lens, scene=render, mask=self.modelMask)
        self.lightcam=base.makeCamera(self.lightbuffer, lens=lens, scene=render, mask=self.lightMask)
        self.plaincam=base.makeCamera(self.lightbuffer, lens=lens, scene=render, mask=self.plainMask)

        # Panda's main camera is not used.
        
        base.cam.node().setActive(0)
        
        # Take explicit control over the order in which the three
        # buffers are rendered.

        self.modelbuffer.setSort(1)
        self.lightbuffer.setSort(2)
        base.win.setSort(3)

        # Within the light buffer, control the order of the two cams.

        self.lightcam.node().getDisplayRegion(0).setSort(1)
        self.plaincam.node().getDisplayRegion(0).setSort(2)

        # By default, panda usually clears the screen before every
        # camera and before every window.  Tell it not to do that.
        # Then, tell it specifically when to clear and what to clear.

        self.modelcam.node().getDisplayRegion(0).disableClears()
        self.lightcam.node().getDisplayRegion(0).disableClears()
        self.plaincam.node().getDisplayRegion(0).disableClears()
        base.cam.node().getDisplayRegion(0).disableClears()
        base.cam2d.node().getDisplayRegion(0).disableClears()
        self.modelbuffer.disableClears()
        base.win.disableClears()

        self.modelbuffer.setClearColorActive(1)
        self.modelbuffer.setClearDepthActive(1)
        self.lightbuffer.setClearColorActive(1)
        self.lightbuffer.setClearColor(Vec4(0,0,0,1))

        # Miscellaneous stuff.
        
        base.disableMouse()
        base.camera.setPos(-9.112,-211.077,46.951)
        base.camera.setHpr(0, -7.5, 2.4)
        base.setBackgroundColor(Vec4(0,0,0,0))
        random.seed()

        # Calculate the projection parameters for the final shader.
        # The math here is too complex to explain in an inline comment,
        # I've put in a full explanation into the HTML intro.

        proj = base.cam.node().getLens().getProjectionMat()
        proj_x = 0.5 * proj.getCell(3,2) / proj.getCell(0,0)
        proj_y = 0.5 * proj.getCell(3,2)
        proj_z = 0.5 * proj.getCell(3,2) / proj.getCell(2,1)
        proj_w = -0.5 - 0.5*proj.getCell(1,2)
        
        # Configure the render state of the model camera.
        
        tempnode = NodePath(PandaNode("temp node"))
        tempnode.setAttrib(AlphaTestAttrib.make(RenderAttrib.MGreaterEqual, 0.5))
        tempnode.setShader(loader.loadShader("model.sha"))
        tempnode.setAttrib(DepthTestAttrib.make(RenderAttrib.MLessEqual))
        self.modelcam.node().setInitialState(tempnode.getState())
        
        # Configure the render state of the light camera.

        tempnode = NodePath(PandaNode("temp node"))
        tempnode.setShader(loader.loadShader("light.sha"))
        tempnode.setShaderInput("texnormal",self.texNormal)
        tempnode.setShaderInput("texalbedo",self.texAlbedo)
        tempnode.setShaderInput("texdepth",self.texDepth)
        tempnode.setShaderInput("proj",Vec4(proj_x,proj_y,proj_z,proj_w))
        tempnode.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OOne, ColorBlendAttrib.OOne))
        tempnode.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullCounterClockwise))
        # The next line causes problems on Linux.
        #tempnode.setAttrib(DepthTestAttrib.make(RenderAttrib.MGreaterEqual))
        tempnode.setAttrib(DepthWriteAttrib.make(DepthWriteAttrib.MOff))
        self.lightcam.node().setInitialState(tempnode.getState())

        # Configure the render state of the plain camera.
        
        rs = RenderState.makeEmpty()
        self.plaincam.node().setInitialState(rs)
        
        # Clear any render attribs on the root node. This is necessary
        # because by default, panda assigns some attribs to the root
        # node.  These default attribs will override the
        # carefully-configured render attribs that we just attached
        # to the cameras.  The simplest solution is to just clear
        # them all out.

        render.setState(RenderState.makeEmpty())

        # My artist created a model in which some of the polygons
        # don't have textures.  This confuses the shader I wrote. 
        # This little hack guarantees that everything has a texture.
        
        white = loader.loadTexture("models/white.jpg")
        render.setTexture(white,0)

        # Create two subroots, to help speed cull traversal.
        
        self.lightroot = NodePath(PandaNode("lightroot"))
        self.lightroot.reparentTo(render)
        self.modelroot = NodePath(PandaNode("modelroot"))
        self.modelroot.reparentTo(render) 
        self.lightroot.hide(BitMask32(self.modelMask))
        self.modelroot.hide(BitMask32(self.lightMask))
        self.modelroot.hide(BitMask32(self.plainMask))

        # Load the model of a forest. Make it visible to the model camera.

        self.forest=NodePath(PandaNode("Forest Root"))
        self.forest.reparentTo(render)
        loader.loadModel("models/icrew").reparentTo(self.forest)
        loader.loadModel("models/mm").reparentTo(self.forest)
        
        self.forest.setScale(4.25, 4.25, 4.25)
        self.forest.setHpr(70,40,3) 
        
        rotation_interval =  self.forest.hprInterval(240,Vec3(220,0,0)) 
        rotation_interval.loop() 

        xrotation_interval =  self.forest.hprInterval(240,self.incFireflyCount, [1.1111111]) 
        xrotation_interval.loop() 

        self.forest.hide(BitMask32(self.lightMask | self.plainMask))

        # Cause the final results to be rendered into the main window on a card.
        
        self.card = self.lightbuffer.getTextureCard()
        self.card.setTexture(self.texFinal)
        self.card.reparentTo(render2d)
        
        # Post the instructions.

        self.title = addTitle("Panda3D: Tutorial - Fireflies using Deferred Shading")
        self.inst1 = addInstructions(0.95,"ESC: Quit")
        self.inst2 = addInstructions(0.90,"Up/Down: More / Fewer Fireflies (Count: unknown)")
        self.inst3 = addInstructions(0.85,"Right/Left: Bigger / Smaller Fireflies (Radius: unknown)")
        self.inst4 = addInstructions(0.80,"V: View the render-to-texture results")

        # Panda contains a built-in viewer that lets you view the results of
        # your render-to-texture operations.  This code configures the viewer.

        base.bufferViewer.setPosition("llcorner")
        base.bufferViewer.setCardSize(0,0.40)
        base.bufferViewer.setLayout("vline")
        self.toggleCards()
        self.toggleCards()

        # Firefly parameters

        self.fireflies = []
        self.sequences = []
        self.scaleseqs = []
        self.glowspheres = []
        self.fireflysize = 1.0
        self.spheremodel = loader.loadModel("misc/sphere")
        self.setFireflySize(25.0)
        while (len(self.fireflies)<5): self.addFirefly()
        self.updateReadout()

        # these allow you to change parameters in realtime

        self.accept("escape", sys.exit, [0])
        self.accept("arrow_up",   self.incFireflyCount, [1.1111111])
        self.accept("arrow_down", self.decFireflyCount, [0.9000000])
        self.accept("arrow_right", self.setFireflySize, [1.1111111])
        self.accept("arrow_left",  self.setFireflySize, [0.9000000])
        self.accept("v", self.toggleCards)
        self.accept("V", self.toggleCards)
        
        
         #---------------  
        # This task increments itself so that the delay between task executions 
        # gradually increases over time. If you do not change task.delayTime
        # the task will simply repeat itself every 2 seconds
    
        #def myFunction(self):
         #   print "Frame:",task.frame
         #   if self.fireflysize>2:
           #    self.fireflysize=self.fireflysize-1
        #return task.again
        #myTask = taskMgr.doMethodLater(1, myFunction, 'tickTask') 
        
        def myFunction(task):
            if len(self.fireflies)>22:   
               self.decFireflyCount, [0.9000000]
            if self.fireflysize>22:
               self.fireflysize=self.fireflysize-5

            return task.again
 
        myTask = taskMgr.doMethodLater(1, myFunction, 'tickTask')
        #--------------------------

        self.nextadd = 0
        taskMgr.add(self.spawnTask, "spawner")

    def makeFBO(self, name, auxrgba):
        # This routine creates an offscreen buffer.  All the complicated
        # parameters are basically demanding capabilities from the offscreen
        # buffer - we demand that it be able to render to texture on every
        # bitplane, that it can support aux bitplanes, that it track
        # the size of the host window, that it can render to texture
        # cumulatively, and so forth.
        winprops = WindowProperties()
        props = FrameBufferProperties()
        props.setRgbColor(1)
        props.setAlphaBits(1)
        props.setDepthBits(1)
        props.setAuxRgba(auxrgba)
        return base.graphicsEngine.makeOutput(
             base.pipe, "model buffer", -2,
             props, winprops,
             GraphicsPipe.BFSizeTrackHost | GraphicsPipe.BFCanBindEvery | 
             GraphicsPipe.BFRttCumulative | GraphicsPipe.BFRefuseWindow,
             base.win.getGsg(), base.win)

    def addFirefly(self):
        pos1 = Point3(random.uniform(-50, 50), random.uniform(-100, 150), random.uniform(-10,80))
        dir = Vec3(random.uniform(-1, 1), random.uniform(-1, 1), random.uniform(-1, 1))
        dir.normalize()
        pos2 = pos1 + (dir*20)
        fly = self.lightroot.attachNewNode(PandaNode("fly"))
        glow = fly.attachNewNode(PandaNode("glow"))
        dot  = fly.attachNewNode(PandaNode("dot"))
        color_r = random.uniform(0.7,1.0)
        color_g = 1.0
        color_b = 0.8
        fly.setShaderInput("lightcolor", color_r, color_g, color_b, 1.0)
        int1 = fly.posInterval(random.uniform(7,12), pos1, pos2)
        int2 = fly.posInterval(random.uniform(7,12), pos2, pos1)
        si1 = fly.scaleInterval(random.uniform(0.8,1.5), Point3(0.2,0.2,0.2), Point3(0.2,0.2,0.2))
        si2 = fly.scaleInterval(random.uniform(1.5,0.8), Point3(1.0,1.0,1.0), Point3(0.2,0.2,0.2))
        si3 = fly.scaleInterval(random.uniform(1.0,2.0), Point3(0.2,0.2,0.2), Point3(1.0,1.0,1.0))
        siseq = Sequence(si1, si2, si3)
        siseq.loop()
        siseq.setT(random.uniform(0,1000))
        seq = Sequence(int1, int2)
        seq.loop()
        self.spheremodel.instanceTo(glow)
        self.spheremodel.instanceTo(dot)
        glow.setScale(self.fireflysize*1.1)
        glow.hide(BitMask32(self.modelMask | self.plainMask))
        dot.setScale(0.6)
        dot.hide(BitMask32(self.modelMask | self.lightMask))
        dot.setColor(color_r, color_g, color_b, 1.0)
        self.fireflies.append(fly)
        self.sequences.append(seq)
        self.glowspheres.append(glow)
        self.scaleseqs.append(siseq)

    def updateReadout(self):
        self.inst2.destroy()
        self.inst2 = addInstructions(0.90,"Up/Down: More / Fewer Fireflies (Currently: "+str(len(self.fireflies))+")")
        self.inst3.destroy()
        self.inst3 = addInstructions(0.85,"Right/Left: Bigger / Smaller Fireflies (Radius: "+str(self.fireflysize)+" ft)")

    def toggleCards(self):
        base.bufferViewer.toggleEnable()
        # When the cards are not visible, I also disable the color clear.
        # This color-clear is actually not necessary, the depth-clear is
        # sufficient for the purposes of the algorithm.
        if (base.bufferViewer.isEnabled()):
            self.modelbuffer.setClearColorActive(1)
        else:
            self.modelbuffer.setClearColorActive(0)

    def incFireflyCount(self, scale):
        if (len(self.fireflies) < 1000):
            n = int((len(self.fireflies) * scale) + 1)
            while (n > len(self.fireflies)):
                self.addFirefly()
            self.updateReadout()
            self.fireflysize=self.fireflysize+10

    def decFireflyCount(self, scale):



        n = int(len(self.fireflies) * scale)
        if (n < 1): n=1
        while (len(self.fireflies) > n):
            self.glowspheres.pop()
            self.sequences.pop().finish()
            self.scaleseqs.pop().finish()
            self.fireflies.pop().removeNode()
        self.updateReadout()

    def setFireflySize(self, n):
        n = n * self.fireflysize
        self.fireflysize = n
        for x in self.glowspheres:
            x.setScale(self.fireflysize * 2.5)
        self.updateReadout()


    def spawnTask(self, task):
        if task.time > self.nextadd:
            self.nextadd = task.time + 1.0
            if (len(self.fireflies) > 30):
                self.decFireflyCount(0.9)
        self.accept('k',  self.incFireflyCount, [1.2511111])
               
       
        return Task.cont
        

    

movie:

 # Load the texture. We could use loader.loadTexture for this,
    # but we want to make sure we get a MovieTexture, since it
    # implements synchronizeTo.
    self.tex = MovieTexture("name")
    assert self.tex.read(MEDIAFILE), "Failed to load video!"
    
    # Set up a fullscreen card to set the video texture on.
    cm = CardMaker("My Fullscreen Card");
    cm.setFrameFullscreenQuad()
    cm.setUvRange(self.tex)
    card = NodePath(cm.generate())
    card.reparentTo(render2d)
    card.setTexture(self.tex)
    card.setTexScale(TextureStage.getDefault(), self.tex.getTexScale())
    self.sound=loader.loadSfx(MEDIAFILE)
    # Synchronize the video to the sound.
    self.tex.synchronizeTo(self.sound)
    
    self.accept('p', self.playpause)
    self.accept('P', self.playpause)
    self.accept('s', self.stopsound)
    self.accept('S', self.stopsound)
    self.accept('m', self.fastforward)
    self.accept('M', self.fastforward)

    def stopsound(self):
      self.sound.stop()
      self.sound.setPlayRate(1.0)

    def fastforward(self):
      print self.sound.status()
      if (self.sound.status() == AudioSound.PLAYING):
        t = self.sound.getTime()
        self.sound.stop()
        if (self.sound.getPlayRate() == 1.0):
          self.sound.setPlayRate(0.5)
        else:
          self.sound.setPlayRate(1.0)
        self.sound.setTime(t)
        self.sound.play()

    def playpause(self):
      if (self.sound.status() == AudioSound.PLAYING):
        t = self.sound.getTime()
        self.sound.stop()
        self.sound.setTime(t)
      else:
        self.sound.play()

/movie

    print "Frameb:"

t=FireflyDemo()

run()

You’re getting that error because when you call anything with SELF it refers to variables and functions within it’s own class. From the code you posted, your movie code does not appear to be within a class at all.

What you need to do is either put all your movie code into it’s own class object, or stick it into your existing FireflyDemo class.

Option 2 is to leave it outside of a class, but remove all the “self.” references by all your variable/object/functions call in that code. But chances are that will produce more errors that will need fixing (i.e. I have no idea if you can just call ‘accept’ to bind keys to anything, etc).

thank you for your suggestion:
now i’m able to play the movie but problem is, that you the see the movie/first frame from the beginning:
-> i want to see the fireflies till someone press the “p”-key. then the movie should start + after the movie you should the the fireflies again?
how cann i do this? thx

#Author: Josh Yelon
#Date: 7/11/2005
#
# See the associated HTML file for an explanation.

#-----------
from panda3d.core import *
# Tell Panda3D to use OpenAL, not FMOD
loadPrcFileData("", "audio-library-name p3openal_audio")
from direct.showbase.DirectObject import DirectObject
from direct.gui.OnscreenText import OnscreenText
import direct.directbase.DirectStart

# The name of the media file.
MEDIAFILE="PandaSneezes.avi"

# Function to put instructions on the screen.
def addInstructions(pos, msg):
    return OnscreenText(text=msg, style=1, fg=(0,0,0,1), mayChange=1,
                        pos=(-1.3, pos), align=TextNode.ALeft, scale = .05, shadow=(1,1,1,1), shadowOffset=(0.1,0.1))

# Function to put title on the screen.
def addTitle(text):
    return OnscreenText(text=text, style=1, fg=(0,0,0,1),
                        pos=(1.3,-0.95), align=TextNode.ARight, scale = .07, shadow=(1,1,1,1), shadowOffset=(0.05,0.05))
#-----------
                        
import direct.directbase.DirectStart
from panda3d.core import FrameBufferProperties, WindowProperties
from panda3d.core import GraphicsPipe,GraphicsOutput
from panda3d.core import Filename,Texture,Shader
from panda3d.core import RenderState, CardMaker
from panda3d.core import PandaNode,TextNode,NodePath
from panda3d.core import RenderAttrib,AlphaTestAttrib,ColorBlendAttrib
from panda3d.core import CullFaceAttrib,DepthTestAttrib,DepthWriteAttrib
from panda3d.core import Point3,Vec3,Vec4,BitMask32
from direct.gui.OnscreenText import OnscreenText
from direct.showbase.DirectObject import DirectObject
from direct.interval.MetaInterval import Sequence
from direct.task.Task import Task
from direct.actor.Actor import Actor
import sys,os,random

# Function to put instructions on the screen.
def addInstructions(pos, msg):
    return OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-21.3, pos), align=TextNode.ALeft, scale = .05)

# Function to put title on the screen.
def addTitle(text):
    return OnscreenText(text=text, style=1, fg=(1,1,1,1),
                        pos=(12.3,-0.95), align=TextNode.ARight, scale = .07)


class FireflyDemo(DirectObject):
    def __init__(self):
        self.n=1
        # Preliminary capabilities check.

        if (base.win.getGsg().getSupportsBasicShaders()==0):
            self.t=addTitle("Firefly Demo: Video driver reports that shaders are not supported.")
            return
        if (base.win.getGsg().getSupportsDepthTexture()==0):
            self.t=addTitle("Firefly Demo: Video driver reports that depth textures are not supported.")
            return
        
        # This algorithm uses two offscreen buffers, one of which has
        # an auxiliary bitplane, and the offscreen buffers share a single
        # depth buffer.  This is a heck of a complicated buffer setup.

        self.modelbuffer = self.makeFBO("model buffer",1)
        self.lightbuffer = self.makeFBO("light buffer",0)
        
        # Creation of a high-powered buffer can fail, if the graphics card
        # doesn't support the necessary OpenGL extensions.

        if (self.modelbuffer == None) or (self.lightbuffer == None):
            self.t=addTitle("Toon Shader: Video driver does not support multiple render targets")
            return

        # Create four render textures: depth, normal, albedo, and final.
        # attach them to the various bitplanes of the offscreen buffers.

        self.texDepth = Texture()
        self.texDepth.setFormat(Texture.FDepthStencil)
        self.texAlbedo = Texture()
        self.texNormal = Texture()
        self.texFinal = Texture()

        self.modelbuffer.addRenderTexture(self.texDepth,  GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPDepthStencil)
        self.modelbuffer.addRenderTexture(self.texAlbedo, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPColor)
        self.modelbuffer.addRenderTexture(self.texNormal, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPAuxRgba0)

        self.lightbuffer.addRenderTexture(self.texFinal,  GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPColor)

        # Set the near and far clipping planes.
        
        base.cam.node().getLens().setNear(50.0)
        base.cam.node().getLens().setFar(500.0)
        lens = base.cam.node().getLens()

        # This algorithm uses three cameras: one to render the models into the
        # model buffer, one to render the lights into the light buffer, and
        # one to render "plain" stuff (non-deferred shaded) stuff into the light
        # buffer.  Each camera has a bitmask to identify it.

        self.modelMask = 1
        self.lightMask = 2
        self.plainMask = 4
        
        self.modelcam=base.makeCamera(self.modelbuffer, lens=lens, scene=render, mask=self.modelMask)
        self.lightcam=base.makeCamera(self.lightbuffer, lens=lens, scene=render, mask=self.lightMask)
        self.plaincam=base.makeCamera(self.lightbuffer, lens=lens, scene=render, mask=self.plainMask)

        # Panda's main camera is not used.
        
        base.cam.node().setActive(0)
        
        # Take explicit control over the order in which the three
        # buffers are rendered.

        self.modelbuffer.setSort(1)
        self.lightbuffer.setSort(2)
        base.win.setSort(3)

        # Within the light buffer, control the order of the two cams.

        self.lightcam.node().getDisplayRegion(0).setSort(1)
        self.plaincam.node().getDisplayRegion(0).setSort(2)

        # By default, panda usually clears the screen before every
        # camera and before every window.  Tell it not to do that.
        # Then, tell it specifically when to clear and what to clear.

        self.modelcam.node().getDisplayRegion(0).disableClears()
        self.lightcam.node().getDisplayRegion(0).disableClears()
        self.plaincam.node().getDisplayRegion(0).disableClears()
        base.cam.node().getDisplayRegion(0).disableClears()
        base.cam2d.node().getDisplayRegion(0).disableClears()
        self.modelbuffer.disableClears()
        base.win.disableClears()

        self.modelbuffer.setClearColorActive(1)
        self.modelbuffer.setClearDepthActive(1)
        self.lightbuffer.setClearColorActive(1)
        self.lightbuffer.setClearColor(Vec4(0,0,0,1))

        # Miscellaneous stuff.
        
        base.disableMouse()
        base.camera.setPos(-9.112,-211.077,46.951)
        base.camera.setHpr(0, -7.5, 2.4)
        base.setBackgroundColor(Vec4(0,0,0,0))
        random.seed()

        # Calculate the projection parameters for the final shader.
        # The math here is too complex to explain in an inline comment,
        # I've put in a full explanation into the HTML intro.

        proj = base.cam.node().getLens().getProjectionMat()
        proj_x = 0.5 * proj.getCell(3,2) / proj.getCell(0,0)
        proj_y = 0.5 * proj.getCell(3,2)
        proj_z = 0.5 * proj.getCell(3,2) / proj.getCell(2,1)
        proj_w = -0.5 - 0.5*proj.getCell(1,2)
        
        # Configure the render state of the model camera.
        
        tempnode = NodePath(PandaNode("temp node"))
        tempnode.setAttrib(AlphaTestAttrib.make(RenderAttrib.MGreaterEqual, 0.5))
        tempnode.setShader(loader.loadShader("model.sha"))
        tempnode.setAttrib(DepthTestAttrib.make(RenderAttrib.MLessEqual))
        self.modelcam.node().setInitialState(tempnode.getState())
        
        # Configure the render state of the light camera.

        tempnode = NodePath(PandaNode("temp node"))
        tempnode.setShader(loader.loadShader("light.sha"))
        tempnode.setShaderInput("texnormal",self.texNormal)
        tempnode.setShaderInput("texalbedo",self.texAlbedo)
        tempnode.setShaderInput("texdepth",self.texDepth)
        tempnode.setShaderInput("proj",Vec4(proj_x,proj_y,proj_z,proj_w))
        tempnode.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OOne, ColorBlendAttrib.OOne))
        tempnode.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullCounterClockwise))
        # The next line causes problems on Linux.
        #tempnode.setAttrib(DepthTestAttrib.make(RenderAttrib.MGreaterEqual))
        tempnode.setAttrib(DepthWriteAttrib.make(DepthWriteAttrib.MOff))
        self.lightcam.node().setInitialState(tempnode.getState())

        # Configure the render state of the plain camera.
        
        rs = RenderState.makeEmpty()
        self.plaincam.node().setInitialState(rs)
        
        # Clear any render attribs on the root node. This is necessary
        # because by default, panda assigns some attribs to the root
        # node.  These default attribs will override the
        # carefully-configured render attribs that we just attached
        # to the cameras.  The simplest solution is to just clear
        # them all out.

        render.setState(RenderState.makeEmpty())

        # My artist created a model in which some of the polygons
        # don't have textures.  This confuses the shader I wrote. 
        # This little hack guarantees that everything has a texture.
        
        white = loader.loadTexture("models/white.jpg")
        render.setTexture(white,0)

        # Create two subroots, to help speed cull traversal.
        
        self.lightroot = NodePath(PandaNode("lightroot"))
        self.lightroot.reparentTo(render)
        self.modelroot = NodePath(PandaNode("modelroot"))
        self.modelroot.reparentTo(render) 
        self.lightroot.hide(BitMask32(self.modelMask))
        self.modelroot.hide(BitMask32(self.lightMask))
        self.modelroot.hide(BitMask32(self.plainMask))

        # Load the model of a forest. Make it visible to the model camera.

        self.forest=NodePath(PandaNode("Forest Root"))
        self.forest.reparentTo(render)
        loader.loadModel("models/icrew").reparentTo(self.forest)
        loader.loadModel("models/mm").reparentTo(self.forest)
        
        self.forest.setScale(4.25, 4.25, 4.25)
        self.forest.setHpr(70,40,3) 
        
        rotation_interval =  self.forest.hprInterval(240,Vec3(220,0,0)) 
        rotation_interval.loop() 

        xrotation_interval =  self.forest.hprInterval(240,self.incFireflyCount, [1.1111111]) 
        xrotation_interval.loop() 

        self.forest.hide(BitMask32(self.lightMask | self.plainMask))

        # Cause the final results to be rendered into the main window on a card.
        
        self.card = self.lightbuffer.getTextureCard()
        self.card.setTexture(self.texFinal)
        self.card.reparentTo(render2d)
        
        # Post the instructions.

        self.title = addTitle("Panda3D: Tutorial - Fireflies using Deferred Shading")
        self.inst1 = addInstructions(0.95,"ESC: Quit")
        self.inst2 = addInstructions(0.90,"Up/Down: More / Fewer Fireflies (Count: unknown)")
        self.inst3 = addInstructions(0.85,"Right/Left: Bigger / Smaller Fireflies (Radius: unknown)")
        self.inst4 = addInstructions(0.80,"V: View the render-to-texture results")

        # Panda contains a built-in viewer that lets you view the results of
        # your render-to-texture operations.  This code configures the viewer.

        base.bufferViewer.setPosition("llcorner")
        base.bufferViewer.setCardSize(0,0.40)
        base.bufferViewer.setLayout("vline")
        self.toggleCards()
        self.toggleCards()

        # Firefly parameters

        self.fireflies = []
        self.sequences = []
        self.scaleseqs = []
        self.glowspheres = []
        self.fireflysize = 1.0
        self.spheremodel = loader.loadModel("misc/sphere")
        self.setFireflySize(25.0)
        while (len(self.fireflies)<5): self.addFirefly()
        self.updateReadout()
        
        
                #self.title = addTitle("Panda3D: Tutorial - Media Player")
    #self.inst1 = addInstructions(0.95,"P: Play/Pause")
    #self.inst2 = addInstructions(0.90,"S: Stop and Rewind")
    #self.inst3 = addInstructions(0.85,"M: Slow Motion / Normal Motion toggle")
    
    # Load the texture. We could use loader.loadTexture for this,
    # but we want to make sure we get a MovieTexture, since it
    # implements synchronizeTo.
        self.tex = MovieTexture("name")
        assert self.tex.read(MEDIAFILE), "Failed to load video!"
    
    # Set up a fullscreen card to set the video texture on.
        cm = CardMaker("My Fullscreen Card");
        cm.setFrameFullscreenQuad()
        cm.setUvRange(self.tex)
        card = NodePath(cm.generate())
        card.reparentTo(render2d)
        card.setTexture(self.tex)
        card.setTexScale(TextureStage.getDefault(), self.tex.getTexScale())
        self.sound=loader.loadSfx(MEDIAFILE)
    # Synchronize the video to the sound.
        self.tex.synchronizeTo(self.sound)
        
        

        # these allow you to change parameters in realtime

        self.accept("escape", sys.exit, [0])
        self.accept("arrow_up",   self.incFireflyCount, [1.1111111])
        self.accept("arrow_down", self.decFireflyCount, [0.9000000])
        self.accept("arrow_right", self.setFireflySize, [1.1111111])
        self.accept("arrow_left",  self.setFireflySize, [0.9000000])
        self.accept("v", self.toggleCards)
        self.accept("V", self.toggleCards)
        
        #--movie
        self.accept('p', self.playpause)
        self.accept('P', self.playpause)
        self.accept('s', self.stopsound)
        self.accept('S', self.stopsound)
        self.accept('m', self.fastforward)
        self.accept('M', self.fastforward)
        #--/movie
        
         #---------------  
        # This task increments itself so that the delay between task executions 
        # gradually increases over time. If you do not change task.delayTime
        # the task will simply repeat itself every 2 seconds
    
        #def myFunction(self):
         #   print "Frame:",task.frame
         #   if self.fireflysize>2:
           #    self.fireflysize=self.fireflysize-1
        #return task.again
        #myTask = taskMgr.doMethodLater(1, myFunction, 'tickTask') 
        
        def myFunction(task):
            if len(self.fireflies)>22:   
               self.decFireflyCount, [0.9000000]
            if self.fireflysize>22:
               self.fireflysize=self.fireflysize-5

            return task.again
 
        myTask = taskMgr.doMethodLater(1, myFunction, 'tickTask')
        #--------------------------

        self.nextadd = 0
        taskMgr.add(self.spawnTask, "spawner")

    def makeFBO(self, name, auxrgba):
        # This routine creates an offscreen buffer.  All the complicated
        # parameters are basically demanding capabilities from the offscreen
        # buffer - we demand that it be able to render to texture on every
        # bitplane, that it can support aux bitplanes, that it track
        # the size of the host window, that it can render to texture
        # cumulatively, and so forth.
        winprops = WindowProperties()
        props = FrameBufferProperties()
        props.setRgbColor(1)
        props.setAlphaBits(1)
        props.setDepthBits(1)
        props.setAuxRgba(auxrgba)
        return base.graphicsEngine.makeOutput(
             base.pipe, "model buffer", -2,
             props, winprops,
             GraphicsPipe.BFSizeTrackHost | GraphicsPipe.BFCanBindEvery | 
             GraphicsPipe.BFRttCumulative | GraphicsPipe.BFRefuseWindow,
             base.win.getGsg(), base.win)

    def addFirefly(self):
        pos1 = Point3(random.uniform(-50, 50), random.uniform(-100, 150), random.uniform(-10,80))
        dir = Vec3(random.uniform(-1, 1), random.uniform(-1, 1), random.uniform(-1, 1))
        dir.normalize()
        pos2 = pos1 + (dir*20)
        fly = self.lightroot.attachNewNode(PandaNode("fly"))
        glow = fly.attachNewNode(PandaNode("glow"))
        dot  = fly.attachNewNode(PandaNode("dot"))
        color_r = random.uniform(0.7,1.0)
        color_g = 1.0
        color_b = 0.8
        fly.setShaderInput("lightcolor", color_r, color_g, color_b, 1.0)
        int1 = fly.posInterval(random.uniform(7,12), pos1, pos2)
        int2 = fly.posInterval(random.uniform(7,12), pos2, pos1)
        si1 = fly.scaleInterval(random.uniform(0.8,1.5), Point3(0.2,0.2,0.2), Point3(0.2,0.2,0.2))
        si2 = fly.scaleInterval(random.uniform(1.5,0.<img src="/uploads/default/original/1X/ae031e9834d19166598edd060b063d44f1829139.gif" width="15" height="15" alt="8)" title="Cool"/>, Point3(1.0,1.0,1.0), Point3(0.2,0.2,0.2))
        si3 = fly.scaleInterval(random.uniform(1.0,2.0), Point3(0.2,0.2,0.2), Point3(1.0,1.0,1.0))
        siseq = Sequence(si1, si2, si3)
        siseq.loop()
        siseq.setT(random.uniform(0,1000))
        seq = Sequence(int1, int2)
        seq.loop()
        self.spheremodel.instanceTo(glow)
        self.spheremodel.instanceTo(dot)
        glow.setScale(self.fireflysize*1.1)
        glow.hide(BitMask32(self.modelMask | self.plainMask))
        dot.setScale(0.6)
        dot.hide(BitMask32(self.modelMask | self.lightMask))
        dot.setColor(color_r, color_g, color_b, 1.0)
        self.fireflies.append(fly)
        self.sequences.append(seq)
        self.glowspheres.append(glow)
        self.scaleseqs.append(siseq)

    def updateReadout(self):
        self.inst2.destroy()
        self.inst2 = addInstructions(0.90,"Up/Down: More / Fewer Fireflies (Currently: "+str(len(self.fireflies))+")")
        self.inst3.destroy()
        self.inst3 = addInstructions(0.85,"Right/Left: Bigger / Smaller Fireflies (Radius: "+str(self.fireflysize)+" ft)")

    def toggleCards(self):
        base.bufferViewer.toggleEnable()
        # When the cards are not visible, I also disable the color clear.
        # This color-clear is actually not necessary, the depth-clear is
        # sufficient for the purposes of the algorithm.
        if (base.bufferViewer.isEnabled()):
            self.modelbuffer.setClearColorActive(1)
        else:
            self.modelbuffer.setClearColorActive(0)

    def incFireflyCount(self, scale):
        if (len(self.fireflies) < 1000):
            n = int((len(self.fireflies) * scale) + 1)
            while (n > len(self.fireflies)):
                self.addFirefly()
            self.updateReadout()
            self.fireflysize=self.fireflysize+10

    def decFireflyCount(self, scale):
        n = int(len(self.fireflies) * scale)
        if (n < 1): n=1
        while (len(self.fireflies) > n):
            self.glowspheres.pop()
            self.sequences.pop().finish()
            self.scaleseqs.pop().finish()
            self.fireflies.pop().removeNode()
        self.updateReadout()

    def setFireflySize(self, n):
        n = n * self.fireflysize
        self.fireflysize = n
        for x in self.glowspheres:
            x.setScale(self.fireflysize * 2.5)
        self.updateReadout()


    def spawnTask(self, task):
        if task.time > self.nextadd:
            self.nextadd = task.time + 1.0
            if (len(self.fireflies) > 30):
                self.decFireflyCount(0.9)
        self.accept('k',  self.incFireflyCount, [1.2511111])
               
       
        return Task.cont
        

 
    print "Frameb:"
    
    
    

#-----------


    


    def stopsound(self):
        self.sound.stop()
        self.sound.setPlayRate(1.0)

    def fastforward(self):
        print self.sound.status()
        if (self.sound.status() == AudioSound.PLAYING):
          t = self.sound.getTime()
          self.sound.stop()
          if (self.sound.getPlayRate() == 1.0):
            self.sound.setPlayRate(0.5)
          else:
            self.sound.setPlayRate(1.0)
          self.sound.setTime(t)
          self.sound.play()

    def playpause(self):
        if (self.sound.status() == AudioSound.PLAYING):
          t = self.sound.getTime()
          self.sound.stop()
          self.sound.setTime(t)
        else:
          self.sound.play()

#---------


t=FireflyDemo()

run()

then hide the movie card :

card.hide()

then show the movie card in playpause() :

card.show()
render.hide()

To know if the movie reaches the end, you could listen to the finished event you define :

    self.sound.setFinishedEvent('soundEnd')
    self.accept('soundEnd', self.soundEnd)

  def soundEnd(self):
      card.hide()
      render.show()

thx,

works fine, i see only the fireflies at the beginning! :slight_smile:

but if i add:

i see the fireflies and hear only the sound of the movie.

if i add:

i get:
NameError: global name ‘card’ is not defined

if i add:

i get:

-> what is wrong?/how can i hide the render correctly? thx

Change card.show() to self.card.show()

Change self.render.hide to render.hide

You might want to read up on variable scope. A global variable like render cannot be called with self. in front of it, that makes python think you are calling a class variable. Same works in reverse, calling card.show tells python you are trying to call a global variable called card instead of a class variable, which needs to be called by self.card when you are using code within that class :slight_smile:

now i got it, thank you very much, helped me a lot!!
if someone is interested in the code (fireflies+mediaplayer+fireflies raise by keyboard, go down in numbers by time), here it is:

code: