framebuffer-feedback.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. #!/usr/bin/env python
  2. # Author: Josh Yelon
  3. #
  4. # This is a tutorial to show one of the simplest applications
  5. # of copy-to-texture: motion trails.
  6. #
  7. from direct.showbase.ShowBase import ShowBase
  8. from panda3d.core import GraphicsOutput
  9. from panda3d.core import Filename, Texture
  10. from panda3d.core import CardMaker
  11. from panda3d.core import NodePath, TextNode
  12. from panda3d.core import AmbientLight, DirectionalLight
  13. from direct.showbase.DirectObject import DirectObject
  14. from direct.gui.OnscreenText import OnscreenText
  15. from direct.task.Task import Task
  16. from direct.actor.Actor import Actor
  17. from random import uniform
  18. import sys
  19. import os
  20. def addInstructions(pos, msg):
  21. return OnscreenText(text=msg, parent=base.a2dTopLeft,
  22. style=1, fg=(1, 1, 1, 1), pos=(0.06, -pos - 0.03),
  23. align=TextNode.ALeft, scale=.05)
  24. class MotionTrails(ShowBase):
  25. def __init__(self):
  26. # Initialize the ShowBase class from which we inherit, which will
  27. # create a window and set up everything we need for rendering into it.
  28. ShowBase.__init__(self)
  29. self.disableMouse()
  30. self.camera.setPos(0, -26, 4)
  31. self.setBackgroundColor(0, 0, 0)
  32. # Create a texture into which we can copy the main window.
  33. # We set it to RTMTriggeredCopyTexture mode, which tells it that we
  34. # want it to copy the window contents into a texture every time we
  35. # call self.win.triggerCopy().
  36. self.tex = Texture()
  37. self.tex.setMinfilter(Texture.FTLinear)
  38. self.win.addRenderTexture(self.tex,
  39. GraphicsOutput.RTMTriggeredCopyTexture)
  40. # Set the initial color to clear the texture to, before rendering it.
  41. # This is necessary because we don't clear the texture while rendering,
  42. # and otherwise the user might see garbled random data from GPU memory.
  43. self.tex.setClearColor((0, 0, 0, 1))
  44. self.tex.clearImage()
  45. # Create another 2D camera. Tell it to render before the main camera.
  46. self.backcam = self.makeCamera2d(self.win, sort=-10)
  47. self.background = NodePath("background")
  48. self.backcam.reparentTo(self.background)
  49. self.background.setDepthTest(0)
  50. self.background.setDepthWrite(0)
  51. self.backcam.node().getDisplayRegion(0).setClearDepthActive(0)
  52. # Obtain two texture cards. One renders before the dragon, the other
  53. # after.
  54. self.bcard = self.win.getTextureCard()
  55. self.bcard.reparentTo(self.background)
  56. self.bcard.setTransparency(1)
  57. self.fcard = self.win.getTextureCard()
  58. self.fcard.reparentTo(self.render2d)
  59. self.fcard.setTransparency(1)
  60. # Initialize one of the nice effects.
  61. self.chooseEffectGhost()
  62. # Add the task that initiates the screenshots.
  63. taskMgr.add(self.takeSnapShot, "takeSnapShot")
  64. # Create some black squares on top of which we will
  65. # place the instructions.
  66. blackmaker = CardMaker("blackmaker")
  67. blackmaker.setColor(0, 0, 0, 1)
  68. blackmaker.setFrame(-1.00, -0.50, 0.65, 1.00)
  69. instcard = NodePath(blackmaker.generate())
  70. instcard.reparentTo(self.render2d)
  71. blackmaker.setFrame(-0.5, 0.5, -1.00, -0.85)
  72. titlecard = NodePath(blackmaker.generate())
  73. titlecard.reparentTo(self.render2d)
  74. # Panda does its best to hide the differences between DirectX and
  75. # OpenGL. But there are a few differences that it cannot hide.
  76. # One such difference is that when OpenGL copies from a
  77. # visible window to a texture, it gets it right-side-up. When
  78. # DirectX does it, it gets it upside-down. There is nothing panda
  79. # can do to compensate except to expose a flag and let the
  80. # application programmer deal with it. You should only do this
  81. # in the rare event that you're copying from a visible window
  82. # to a texture.
  83. if self.win.getGsg().getCopyTextureInverted():
  84. print("Copy texture is inverted.")
  85. self.bcard.setScale(1, 1, -1)
  86. self.fcard.setScale(1, 1, -1)
  87. # Put up the instructions
  88. title = OnscreenText(text="Panda3D: Tutorial - Motion Trails",
  89. fg=(1, 1, 1, 1), parent=base.a2dBottomCenter,
  90. pos=(0, 0.1), scale=.08)
  91. instr0 = addInstructions(0.06, "Press ESC to exit")
  92. instr1 = addInstructions(0.12, "Press 1: Ghost effect")
  93. instr2 = addInstructions(0.18, "Press 2: PaintBrush effect")
  94. instr3 = addInstructions(0.24, "Press 3: Double Vision effect")
  95. instr4 = addInstructions(0.30, "Press 4: Wings of Blue effect")
  96. instr5 = addInstructions(0.36, "Press 5: Whirlpool effect")
  97. # Enable the key events
  98. self.accept("escape", sys.exit, [0])
  99. self.accept("1", self.chooseEffectGhost)
  100. self.accept("2", self.chooseEffectPaintBrush)
  101. self.accept("3", self.chooseEffectDoubleVision)
  102. self.accept("4", self.chooseEffectWingsOfBlue)
  103. self.accept("5", self.chooseEffectWhirlpool)
  104. def takeSnapShot(self, task):
  105. if task.time > self.nextclick:
  106. self.nextclick += 1.0 / self.clickrate
  107. if self.nextclick < task.time:
  108. self.nextclick = task.time
  109. self.win.triggerCopy()
  110. return Task.cont
  111. def chooseEffectGhost(self):
  112. self.setBackgroundColor(0, 0, 0, 1)
  113. self.bcard.hide()
  114. self.fcard.show()
  115. self.fcard.setColor(1.0, 1.0, 1.0, 0.99)
  116. self.fcard.setScale(1.00)
  117. self.fcard.setPos(0, 0, 0)
  118. self.fcard.setR(0)
  119. self.clickrate = 30
  120. self.nextclick = 0
  121. def chooseEffectPaintBrush(self):
  122. self.setBackgroundColor(0, 0, 0, 1)
  123. self.bcard.show()
  124. self.fcard.hide()
  125. self.bcard.setColor(1, 1, 1, 1)
  126. self.bcard.setScale(1.0)
  127. self.bcard.setPos(0, 0, 0)
  128. self.bcard.setR(0)
  129. self.clickrate = 10000
  130. self.nextclick = 0
  131. def chooseEffectDoubleVision(self):
  132. self.setBackgroundColor(0, 0, 0, 1)
  133. self.bcard.show()
  134. self.bcard.setColor(1, 1, 1, 1)
  135. self.bcard.setScale(1.0)
  136. self.bcard.setPos(-0.05, 0, 0)
  137. self.bcard.setR(0)
  138. self.fcard.show()
  139. self.fcard.setColor(1, 1, 1, 0.60)
  140. self.fcard.setScale(1.0)
  141. self.fcard.setPos(0.05, 0, 0)
  142. self.fcard.setR(0)
  143. self.clickrate = 10000
  144. self.nextclick = 0
  145. def chooseEffectWingsOfBlue(self):
  146. self.setBackgroundColor(0, 0, 0, 1)
  147. self.fcard.hide()
  148. self.bcard.show()
  149. self.bcard.setColor(1.0, 0.90, 1.0, 254.0 / 255.0)
  150. self.bcard.setScale(1.1, 1, 0.95)
  151. self.bcard.setPos(0, 0, 0.05)
  152. self.bcard.setR(0)
  153. self.clickrate = 30
  154. self.nextclick = 0
  155. def chooseEffectWhirlpool(self):
  156. self.setBackgroundColor(0, 0, 0, 1)
  157. self.bcard.show()
  158. self.fcard.hide()
  159. self.bcard.setColor(1, 1, 1, 1)
  160. self.bcard.setScale(0.999)
  161. self.bcard.setPos(0, 0, 0)
  162. self.bcard.setR(1)
  163. self.clickrate = 10000
  164. self.nextclick = 0
  165. t = MotionTrails()
  166. character = Actor()
  167. character.loadModel('models/dancer')
  168. character.reparentTo(t.render)
  169. character.loadAnims({'win': 'models/dancer'})
  170. character.loop('win')
  171. # character.hprInterval(15, LPoint3(360, 0,0)).loop()
  172. # put some lighting on the model
  173. dlight = DirectionalLight('dlight')
  174. alight = AmbientLight('alight')
  175. dlnp = t.render.attachNewNode(dlight)
  176. alnp = t.render.attachNewNode(alight)
  177. dlight.setColor((1.0, 0.9, 0.8, 1))
  178. alight.setColor((0.2, 0.3, 0.4, 1))
  179. dlnp.setHpr(0, -60, 0)
  180. t.render.setLight(dlnp)
  181. t.render.setLight(alnp)
  182. t.run()