advanced.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. #!/usr/bin/env python
  2. # Author: Kwasi Mensah ([email protected])
  3. # Date: 7/25/2005
  4. from direct.showbase.ShowBase import ShowBase
  5. from panda3d.core import Filename, Shader
  6. from panda3d.core import PandaNode, NodePath
  7. from panda3d.core import ColorBlendAttrib
  8. from panda3d.core import AmbientLight, DirectionalLight
  9. from panda3d.core import TextNode, LPoint3, LVector4
  10. from direct.showbase.DirectObject import DirectObject
  11. from direct.gui.OnscreenText import OnscreenText
  12. from direct.actor.Actor import Actor
  13. import sys
  14. import os
  15. # Function to put instructions on the screen.
  16. def addInstructions(pos, msg):
  17. return OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1),
  18. parent=base.a2dTopLeft, align=TextNode.ALeft,
  19. pos=(0.08, -pos - 0.04), scale=.05)
  20. # Function to put title on the screen.
  21. def addTitle(text):
  22. return OnscreenText(text=text, style=1, fg=(1, 1, 1, 1),
  23. parent=base.a2dBottomRight, align=TextNode.ARight,
  24. pos=(-0.1, 0.09), scale=.08)
  25. # This function is responsible for setting up the two blur filters.
  26. # It just makes a temp Buffer, puts a screen aligned card, and then sets
  27. # the appropiate shader to do all the work. Gaussian blurs are decomposable
  28. # into a two-pass algorithm which is faster than the equivalent one-pass
  29. # algorithm, so we do it in two passes: one pass that blurs in the horizontal
  30. # direction, and one in the vertical direction.
  31. def makeFilterBuffer(srcbuffer, name, sort, prog):
  32. blurBuffer = base.win.makeTextureBuffer(name, 512, 512)
  33. blurBuffer.setSort(sort)
  34. blurBuffer.setClearColor(LVector4(1, 0, 0, 1))
  35. blurCamera = base.makeCamera2d(blurBuffer)
  36. blurScene = NodePath("new Scene")
  37. blurCamera.node().setScene(blurScene)
  38. shader = loader.loadShader(prog)
  39. card = srcbuffer.getTextureCard()
  40. card.reparentTo(blurScene)
  41. card.setShader(shader)
  42. return blurBuffer
  43. class GlowDemo(ShowBase):
  44. def __init__(self):
  45. # Initialize the ShowBase class from which we inherit, which will
  46. # create a window and set up everything we need for rendering into it.
  47. ShowBase.__init__(self)
  48. base.disableMouse()
  49. base.setBackgroundColor(0, 0, 0)
  50. camera.setPos(0, -50, 0)
  51. # Check video card capabilities.
  52. if not base.win.getGsg().getSupportsBasicShaders():
  53. addTitle(
  54. "Glow Filter: Video driver reports that Cg shaders are not supported.")
  55. return
  56. # Post the instructions
  57. self.title = addTitle("Panda3D: Tutorial - Glow Filter")
  58. self.inst1 = addInstructions(0.06, "ESC: Quit")
  59. self.inst2 = addInstructions(0.12, "Space: Toggle Glow Filter On/Off")
  60. self.inst3 = addInstructions(0.18, "Enter: Toggle Running/Spinning")
  61. self.inst4 = addInstructions(0.24, "V: View the render-to-texture results")
  62. # Create the shader that will determime what parts of the scene will
  63. # glow
  64. glowShader = loader.loadShader("shaders/glowShader.sha")
  65. # load our model
  66. self.tron = Actor()
  67. self.tron.loadModel("models/tron")
  68. self.tron.loadAnims({"running": "models/tron_anim"})
  69. self.tron.reparentTo(render)
  70. self.interval = self.tron.hprInterval(60, LPoint3(360, 0, 0))
  71. self.interval.loop()
  72. self.isRunning = False
  73. # put some lighting on the tron model
  74. dlight = DirectionalLight('dlight')
  75. alight = AmbientLight('alight')
  76. dlnp = render.attachNewNode(dlight)
  77. alnp = render.attachNewNode(alight)
  78. dlight.setColor(LVector4(1.0, 0.7, 0.2, 1))
  79. alight.setColor(LVector4(0.2, 0.2, 0.2, 1))
  80. dlnp.setHpr(0, -60, 0)
  81. render.setLight(dlnp)
  82. render.setLight(alnp)
  83. # create the glow buffer. This buffer renders like a normal scene,
  84. # except that only the glowing materials should show up nonblack.
  85. glowBuffer = base.win.makeTextureBuffer("Glow scene", 512, 512)
  86. glowBuffer.setSort(-3)
  87. glowBuffer.setClearColor(LVector4(0, 0, 0, 1))
  88. # We have to attach a camera to the glow buffer. The glow camera
  89. # must have the same frustum as the main camera. As long as the aspect
  90. # ratios match, the rest will take care of itself.
  91. glowCamera = base.makeCamera(
  92. glowBuffer, lens=base.cam.node().getLens())
  93. # Tell the glow camera to use the glow shader
  94. tempnode = NodePath(PandaNode("temp node"))
  95. tempnode.setShader(glowShader)
  96. glowCamera.node().setInitialState(tempnode.getState())
  97. # set up the pipeline: from glow scene to blur x to blur y to main
  98. # window.
  99. blurXBuffer = makeFilterBuffer(
  100. glowBuffer, "Blur X", -2, "shaders/XBlurShader.sha")
  101. blurYBuffer = makeFilterBuffer(
  102. blurXBuffer, "Blur Y", -1, "shaders/YBlurShader.sha")
  103. self.finalcard = blurYBuffer.getTextureCard()
  104. self.finalcard.reparentTo(render2d)
  105. # This attribute is used to add the results of the post-processing
  106. # effects to the existing framebuffer image, rather than replace it.
  107. # This is mainly useful for glow effects like ours.
  108. self.finalcard.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd))
  109. # Panda contains a built-in viewer that lets you view the results of
  110. # your render-to-texture operations. This code configures the viewer.
  111. self.accept("v", base.bufferViewer.toggleEnable)
  112. self.accept("V", base.bufferViewer.toggleEnable)
  113. base.bufferViewer.setPosition("llcorner")
  114. base.bufferViewer.setLayout("hline")
  115. base.bufferViewer.setCardSize(0.652, 0)
  116. # event handling
  117. self.accept("space", self.toggleGlow)
  118. self.accept("enter", self.toggleDisplay)
  119. self.accept("escape", sys.exit, [0])
  120. self.glowOn = True
  121. def toggleGlow(self):
  122. if self.glowOn:
  123. self.finalcard.reparentTo(hidden)
  124. else:
  125. self.finalcard.reparentTo(render2d)
  126. self.glowOn = not(self.glowOn)
  127. def toggleDisplay(self):
  128. self.isRunning = not(self.isRunning)
  129. if not(self.isRunning):
  130. camera.setPos(0, -50, 0)
  131. self.tron.stop("running")
  132. self.tron.pose("running", 0)
  133. self.interval.loop()
  134. else:
  135. camera.setPos(0, -170, 3)
  136. self.interval.finish()
  137. self.tron.setHpr(0, 0, 0)
  138. self.tron.loop("running")
  139. demo = GlowDemo()
  140. demo.run()