bharling
15-11-2008 21:25:43
Hi all,
heres an update to the PSSM demo that includes caelum integration, am posting here because it looks nice , and theres one pitfall i hit when doing it. On directX you've got to disable caelum fog handling otherwise your mesh may well be completely white
screenshots:
http://imagebin.org/31262
http://imagebin.org/31263
you will need to add the caelum resources to the pssm demo in resources.cfg:
save this in the PSSM folder and run
heres an update to the PSSM demo that includes caelum integration, am posting here because it looks nice , and theres one pitfall i hit when doing it. On directX you've got to disable caelum fog handling otherwise your mesh may well be completely white
screenshots:
http://imagebin.org/31262
http://imagebin.org/31263
you will need to add the caelum resources to the pssm demo in resources.cfg:
[Bootstrap]
Zip=../media/packs/OgreCore.zip
[PSSMMedia]
FileSystem=./Media
FileSystem=../caelum/media
save this in the PSSM folder and run
# This code is in the Public Domain
# -----------------------------------------------------------------------------
# This source file is part of Python-Ogre
# For the latest info, see http://python-ogre.org/
#
# It is likely based on original code from OGRE and/or PyOgre
# For the latest info, see http://www.ogre3d.org/
#
# You may use this sample code for anything you like, it is not covered by the
# LGPL.
# -----------------------------------------------------------------------------
# NOTE:
# This demo includes meshes and shaders by lf3thn4d
# see below for more details:
# http://www.ogre3d.org/phpBB2/viewtopic.php?t=41801&highlight=pssm
# Authors Note:
# This demo seems to perform much better on ATI cards than NVIDIA!
import sys
sys.path.insert(0,'..')
import PythonOgreConfig
import ogre.renderer.OGRE as ogre
import ogre.io.OIS as ois
import ogre.addons.caelum as caelum
import SampleFramework as sf
import psyco
psyco.full()
class PSSMDemoFrameListener(sf.FrameListener):
def __init__(self, rw, cam, light):
sf.FrameListener.__init__(self, rw, cam)
self.light = light
self.angle = ogre.Math.PI / 2
self.radius = 1000
def frameStarted(self, evt):
self.angle += evt.timeSinceLastFrame
xpos = self.radius * ogre.Math.Sin( ogre.Degree( self.angle ) * 5.0 )
zpos = self.radius * ogre.Math.Cos( ogre.Degree( self.angle ) * 5.0 )
pos = ogre.Vector3( xpos, 400, zpos )
self.light.setPosition( pos )
dirvec = -self.light.getPosition()
dirvec.normalise()
self.light.setDirection( dirvec )
return sf.FrameListener.frameStarted(self, evt)
class CaelumSampleFrameListener(sf.FrameListener):
def __init__(self, win, cam, app ):
sf.FrameListener.__init__(self, win, cam)
self.sceneManager = cam.getSceneManager()
self.window = win
self.camera = cam
self.paused=False
self.app = app
# Pick components to create in the demo.
# You can comment any of those and it should still work
# Trying to disable one of these can be useful in finding problems.
componentMask = caelum.CaelumSystem.CaelumComponent (
caelum.CaelumSystem.CAELUM_COMPONENT_SUN |
caelum.CaelumSystem.CAELUM_COMPONENT_MOON |
caelum.CaelumSystem.CAELUM_COMPONENT_SKY_DOME |
caelum.CaelumSystem.CAELUM_COMPONENT_IMAGE_STARFIELD |
##caelum.CaelumSystem.CAELUM_COMPONENT_POINT_STARFIELD |
caelum.CaelumSystem.CAELUM_COMPONENT_CLOUDS |
0);
componentMask = caelum.CaelumSystem.CAELUM_COMPONENTS_DEFAULT
## Initialise CaelumSystem.
self.mCaelumSystem = caelum.CaelumSystem (ogre.Root.getSingletonPtr(), self.sceneManager, componentMask)
## Set time acceleration.
self.mCaelumSystem.getUniversalClock ().setTimeScale (512)
self.mCaelumSystem.getSun().setAmbientMultiplier(ogre.ColourValue(1.0,1.0,1.0,1.0))
self.mCaelumSystem.getSun().setSpecularMultiplier(ogre.ColourValue(1.0,1.0,1.0,1.0))
#self.mCaelumSystem.getMoon().setAutoDisable(True)
self.mCaelumSystem.getMoon().setAutoDisableThreshold(5.0)
self.mCaelumSystem.setManageSceneFog(False)
## Register caelum as a listener.
self.app.renderWindow.addListener (self.mCaelumSystem)
ogre.Root.getSingletonPtr().addFrameListener (self.mCaelumSystem)
self.UpdateSpeedFactor(self.mCaelumSystem.getUniversalClock ().getTimeScale ())
self.timeTillNextUpdate = 0
## Update speed factors.
def UpdateSpeedFactor(self, factor):
self.speedFactor = factor;
if self.paused:
self.mCaelumSystem.getUniversalClock ().setTimeScale (0)
else:
self.mCaelumSystem.getUniversalClock ().setTimeScale (self.speedFactor)
def frameEnded(self, evt):
if not sf.FrameListener.frameEnded(self, evt):
return False
## Stop key repeat for these keys.
## keyboard input
self.timeTillNextUpdate -= evt.timeSinceLastFrame
if (self.timeTillNextUpdate<= 0):
if (self.Keyboard.isKeyDown (ois.KC_SPACE)):
self.timeTillNextUpdate = 1
self.paused = not self.paused
self.UpdateSpeedFactor(self.speedFactor)
if (self.Keyboard.isKeyDown(ois.KC_X)):
self.timeTillNextUpdate = 0.25
self.UpdateSpeedFactor(self.speedFactor/2)
if (self.Keyboard.isKeyDown(ois.KC_C)):
self.timeTillNextUpdate = 0.25
self.UpdateSpeedFactor(self.speedFactor*2)
if (self.Keyboard.isKeyDown(ois.KC_Z)):
self.timeTillNextUpdate = 1
self.UpdateSpeedFactor(self.speedFactor * -1)
return True
class ApplicationPSSM(sf.Application):
def __del__(self):
del self.pssmSetup
def _createScene(self):
self.sceneManager.setShadowTechnique(ogre.SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED)
# 3 textures per directional light
self.sceneManager.setShadowTextureCountPerLightType(ogre.Light.LT_DIRECTIONAL, 3);
self.sceneManager.setShadowTextureSettings(2048, 3, ogre.PF_FLOAT32_R);
self.sceneManager.setShadowTextureSelfShadow(True);
# Set up caster material - this is just a standard depth/shadow map caster
self.sceneManager.setShadowTextureCasterMaterial("shadow_caster");
## self.camera.setNearClipDistance(1.0)
self.camera.setFarClipDistance(9000*3)
self.camera.setNearClipDistance(0.5)
self.sceneManager.setFog(ogre.FogMode.FOG_EXP2) #FogMode.FOG_NONE [,class Ogre::ColourValue= [,float=0.001 [,float=0.0 [,float=1.0]]]]])
## Set camera clip distances. It's important to test with
## an infinite clip distance.
#self.camera.setFarClipDistance(9999*3)
#self.sceneManager.setAmbientLight ( ogre.ColourValue(0,0,0 ))
# shadow camera setup
self.pssmSetup = ogre.PSSMShadowCameraSetup()
self.pssmSetup.calculateSplitPoints(3, self.camera.getNearClipDistance(), 3000)#self.camera.getFarClipDistance())
self.pssmSetup.setSplitPadding(4)
self.pssmSetup.setUseSimpleOptimalAdjust(True)
## self.pssmSetup.setOptimalAdjustFactor(0, 1.5)
## self.pssmSetup.setOptimalAdjustFactor(1, 1);
## self.pssmSetup.setOptimalAdjustFactor(2, 0.5)
self.sceneManager.setShadowCameraSetup(self.pssmSetup)
# setup the sun light.
#self.sceneManager.setAmbientLight(ogre.ColourValue(0.4, 0.4, 0.5));
## self.mSunLight = self.sceneManager.createLight("_SunLight")
## self.mSunLight.setType(ogre.Light.LT_DIRECTIONAL)
## self.mSunLight.setDirection(ogre.Vector3(-1, -1, -1))
## self.mSunLight.setDiffuseColour(ogre.ColourValue(1, 1, 1))
## self.mSunLight.setSpecularColour(ogre.ColourValue(1,1,1))
# Create the Mesh -
# Note Mesh and Shaders courtesy of lf3thn4d
cityNode = self.sceneManager.getRootSceneNode().createChildSceneNode()
cityEntity = self.sceneManager.createEntity("City", "city.mesh")
cityNode.attachObject(cityEntity)
cityNode.setScale(10,10,10)
splitPoints = ogre.Vector4(0,0,0,0)
splitPointList = self.pssmSetup.getSplitPoints();
mat = ogre.MaterialManager.getSingleton().getByName("city")
splitPoints.y = splitPointList[1]
splitPoints.z = splitPointList[2]
mat.getTechnique(0).getPass(1).getFragmentProgramParameters().setNamedConstant("pssmSplitPoints", splitPoints)
#self._createDebugShadowOverlays()
def _createDebugShadowOverlays(self):
baseWhite = ogre.MaterialManager.getSingletonPtr().getByName("BaseWhite")
DepthShadowTexture = baseWhite.clone("DepthShadowTexture0")
textureUnit = DepthShadowTexture.getTechnique(0).getPass(0).createTextureUnitState()
tex = self.sceneManager.getShadowTexture(0)
textureUnit.setTextureName(tex.getName())
DepthShadowTexture = baseWhite.clone("DepthShadowTexture1")
textureUnit = DepthShadowTexture.getTechnique(0).getPass(0).createTextureUnitState()
tex = self.sceneManager.getShadowTexture(1)
textureUnit.setTextureName(tex.getName())
DepthShadowTexture = baseWhite.clone("DepthShadowTexture2")
textureUnit = DepthShadowTexture.getTechnique(0).getPass(0).createTextureUnitState()
tex = self.sceneManager.getShadowTexture(2)
textureUnit.setTextureName(tex.getName())
overlayManager = ogre.OverlayManager.getSingleton()
# Create an overlay
self.mDebugOverlay = overlayManager.create("OverlayName")
# Create a panel
panel = overlayManager.createOverlayElement("Panel", "PanelName0")
panel.setMetricsMode(ogre.GMM_PIXELS)
panel.setPosition(10, 10)
panel.setDimensions(100, 100)
panel.setMaterialName("DepthShadowTexture0") # Optional background material
self.mDebugOverlay.add2D(panel)
panel = overlayManager.createOverlayElement("Panel", "PanelName1")
panel.setMetricsMode(ogre.GMM_PIXELS)
panel.setPosition(120, 10)
panel.setDimensions(100, 100)
panel.setMaterialName("DepthShadowTexture1") # Optional background material
self.mDebugOverlay.add2D(panel)
panel = overlayManager.createOverlayElement("Panel", "PanelName2")
panel.setMetricsMode(ogre.GMM_PIXELS)
panel.setPosition(230, 10)
panel.setDimensions(100, 100)
panel.setMaterialName("DepthShadowTexture2") # Optional background material
self.mDebugOverlay.add2D(panel)
self.mDebugOverlay.show()
def _createFrameListener(self):
#self.frameListener = PSSMDemoFrameListener(self.renderWindow, self.camera, self.mSunLight)
#self.root.addFrameListener(self.frameListener)
self.FrameListener = CaelumSampleFrameListener (self.renderWindow, self.camera, self)
self.root.addFrameListener (self.FrameListener)
if __name__ == '__main__':
import exceptions,sys
try:
application = ApplicationPSSM()
application.go()
except ogre.OgreException, e:
print e