main.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #!/usr/bin/env python
  2. # Author: Tree Form [email protected]
  3. from direct.showbase.ShowBase import ShowBase
  4. from panda3d.core import FrameBufferProperties, TextNode, BitMask32, LPoint3
  5. from panda3d.core import WindowProperties, GraphicsOutput, Texture, GraphicsPipe
  6. from direct.showbase.DirectObject import DirectObject
  7. from direct.gui.OnscreenText import OnscreenText
  8. from sys import exit
  9. # Function to put instructions on the screen.
  10. def addInstructions(pos, msg):
  11. return OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1),
  12. pos=(-1.25, pos), align=TextNode.ALeft, scale=.05)
  13. # Function to put title on the screen.
  14. def addTitle(text):
  15. return OnscreenText(text=text, style=1, fg=(1, 1, 1, 1), shadow=(0, 0, 0, 1),
  16. pos=(1.25, -0.95), align=TextNode.ARight, scale=.07)
  17. class DistortionDemo(ShowBase):
  18. def __init__(self):
  19. # Initialize the ShowBase class from which we inherit, which will
  20. # create a window and set up everything we need for rendering into it.
  21. ShowBase.__init__(self)
  22. if not base.win.getGsg().getSupportsBasicShaders():
  23. t = addTitle("Distortion Demo: Video driver says Cg shaders not supported.")
  24. return
  25. self.disableMouse()
  26. self.setBackgroundColor(0, 0, 0)
  27. # Show the instructions
  28. self.title = addTitle("Panda3D: Tutorial - Distortion Effect")
  29. self.inst1 = addInstructions(0.92, "ESC: Quit")
  30. self.inst2 = addInstructions(0.86, "Space: Toggle distortion filter On/Off")
  31. self.inst4 = addInstructions(0.80, "V: View the render-to-texture results")
  32. # Load background
  33. self.seascape = loader.loadModel("models/plane")
  34. self.seascape.reparentTo(render)
  35. self.seascape.setPosHpr(0, 145, 0, 0, 0, 0)
  36. self.seascape.setScale(100)
  37. self.seascape.setTexture(loader.loadTexture("models/ocean.jpg"))
  38. # Create the distortion buffer. This buffer renders like a normal
  39. # scene,
  40. self.distortionBuffer = self.makeFBO("model buffer")
  41. self.distortionBuffer.setSort(-3)
  42. self.distortionBuffer.setClearColor((0, 0, 0, 0))
  43. # We have to attach a camera to the distortion buffer. The distortion camera
  44. # must have the same frustum as the main camera. As long as the aspect
  45. # ratios match, the rest will take care of itself.
  46. distortionCamera = self.makeCamera(self.distortionBuffer, scene=render,
  47. lens=self.cam.node().getLens(), mask=BitMask32.bit(4))
  48. # load the object with the distortion
  49. self.distortionObject = loader.loadModel("models/boat")
  50. self.distortionObject.setScale(1)
  51. self.distortionObject.setPos(0, 20, -3)
  52. self.distortionObject.hprInterval(10, LPoint3(360, 0, 0)).loop()
  53. self.distortionObject.reparentTo(render)
  54. # Create the shader that will determime what parts of the scene will
  55. # distortion
  56. distortionShader = loader.loadShader("distortion.sha")
  57. self.distortionObject.setShader(distortionShader)
  58. self.distortionObject.hide(BitMask32.bit(4))
  59. # Textures
  60. tex1 = loader.loadTexture("models/water.png")
  61. self.distortionObject.setShaderInput("waves", tex1)
  62. self.texDistortion = Texture()
  63. self.distortionBuffer.addRenderTexture(
  64. self.texDistortion, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPColor)
  65. self.distortionObject.setShaderInput("screen", self.texDistortion)
  66. # Panda contains a built-in viewer that lets you view the results of
  67. # your render-to-texture operations. This code configures the viewer.
  68. self.accept("v", self.bufferViewer.toggleEnable)
  69. self.accept("V", self.bufferViewer.toggleEnable)
  70. self.bufferViewer.setPosition("llcorner")
  71. self.bufferViewer.setLayout("hline")
  72. self.bufferViewer.setCardSize(0.652, 0)
  73. # event handling
  74. self.accept("space", self.toggleDistortion)
  75. self.accept("escape", exit, [0])
  76. self.distortionOn = True
  77. def makeFBO(self, name):
  78. # This routine creates an offscreen buffer. All the complicated
  79. # parameters are basically demanding capabilities from the offscreen
  80. # buffer - we demand that it be able to render to texture on every
  81. # bitplane, that it can support aux bitplanes, that it track
  82. # the size of the host window, that it can render to texture
  83. # cumulatively, and so forth.
  84. winprops = WindowProperties()
  85. props = FrameBufferProperties()
  86. props.setRgbColor(1)
  87. return self.graphicsEngine.makeOutput(
  88. self.pipe, "model buffer", -2, props, winprops,
  89. GraphicsPipe.BFSizeTrackHost | GraphicsPipe.BFRefuseWindow,
  90. self.win.getGsg(), self.win)
  91. def toggleDistortion(self):
  92. # Toggles the distortion on/off.
  93. if self.distortionOn:
  94. self.distortionObject.hide()
  95. else:
  96. self.distortionObject.show()
  97. self.distortionOn = not(self.distortionOn)
  98. demo = DistortionDemo()
  99. demo.run()