RigsofRods
Soft-body Physics Simulation
ShadowManager.cpp
Go to the documentation of this file.
1 /*
2  This source file is part of Rigs of Rods
3  Copyright 2005-2012 Pierre-Michel Ricordel
4  Copyright 2007-2012 Thomas Fischer
5 
6  For more information, see http://www.rigsofrods.org/
7 
8  Rigs of Rods is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License version 3, as
10  published by the Free Software Foundation.
11 
12  Rigs of Rods is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include "ShadowManager.h"
22 
23 #include "Actor.h"
24 #include "CameraManager.h"
25 #include "GfxScene.h"
26 
27 #include <Ogre.h>
28 #include <Terrain/OgreTerrain.h>
29 #include <Overlay/OgreOverlayManager.h>
30 #include <Overlay/OgreOverlayContainer.h>
31 #include <Overlay/OgreOverlay.h>
32 #include <OgreMaterialManager.h>
33 
34 using namespace Ogre;
35 using namespace RoR;
36 
37 ShadowManager::ShadowManager()
38 {
39  PSSM_Shadows.mPSSMSetup.setNull();
40  PSSM_Shadows.mDepthShadows = false;
41  PSSM_Shadows.ShadowsTextureNum = 3;
42  PSSM_Shadows.Quality = RoR::App::gfx_shadow_quality->getInt(); //0 = Low quality, 1 = mid, 2 = hq, 3 = ultra
43 }
44 
45 ShadowManager::~ShadowManager()
46 {
47 }
48 
49 void ShadowManager::loadConfiguration()
50 {
51  this->updateShadowTechnique(); // Config handled by RoR::App
52 }
53 
54 int ShadowManager::updateShadowTechnique()
55 {
56  float scoef = 0.5;
57  App::GetGfxScene()->GetSceneManager()->setShadowColour(Ogre::ColourValue(0.563 + scoef, 0.578 + scoef, 0.625 + scoef));
58  App::GetGfxScene()->GetSceneManager()->setShowDebugShadows(false);
59 
60  if (App::gfx_shadow_type->getEnum<GfxShadowType>() == GfxShadowType::PSSM)
61  {
62  processPSSM();
63  if (App::GetGfxScene()->GetSceneManager()->getShowDebugShadows())
64  {
65  // add the overlay elements to show the shadow maps:
66  // init overlay elements
67  OverlayManager& mgr = Ogre::OverlayManager::getSingleton();
68  Overlay* overlay = mgr.create("DebugOverlay");
69 
70  for (int i = 0; i < PSSM_Shadows.ShadowsTextureNum; ++i)
71  {
72  TexturePtr tex = App::GetGfxScene()->GetSceneManager()->getShadowTexture(i);
73 
74  // Set up a debug panel to display the shadow
75  MaterialPtr debugMat = MaterialManager::getSingleton().create("Ogre/DebugTexture" + StringConverter::toString(i), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
76  debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false);
77  TextureUnitState* t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(tex->getName());
78  t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
79 
80  OverlayContainer* debugPanel = (OverlayContainer*)(OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugTexPanel" + StringConverter::toString(i)));
81  debugPanel->_setPosition(0.8, i * 0.25);
82  debugPanel->_setDimensions(0.2, 0.24);
83  debugPanel->setMaterialName(debugMat->getName());
84  debugPanel->setEnabled(true);
85  overlay->add2D(debugPanel);
86  overlay->show();
87  }
88  }
89  }
90  return 0;
91 }
92 
93 void ShadowManager::processPSSM()
94 {
95  App::GetGfxScene()->GetSceneManager()->setShadowTechnique(Ogre::SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED);
96 
97  App::GetGfxScene()->GetSceneManager()->setShadowDirectionalLightExtrusionDistance(299.0f);
98  App::GetGfxScene()->GetSceneManager()->setShadowFarDistance(350.0f);
99  App::GetGfxScene()->GetSceneManager()->setShadowTextureCountPerLightType(Ogre::Light::LT_DIRECTIONAL, PSSM_Shadows.ShadowsTextureNum);
100  App::GetGfxScene()->GetSceneManager()->setShadowTextureCount(PSSM_Shadows.ShadowsTextureNum);
101 
102  App::GetGfxScene()->GetSceneManager()->setShadowTextureSelfShadow(true);
103  App::GetGfxScene()->GetSceneManager()->setShadowCasterRenderBackFaces(true);
104 
105  //Caster is set via materials
106  MaterialPtr shadowMat = MaterialManager::getSingleton().getByName("Ogre/shadow/depth/caster");
107  App::GetGfxScene()->GetSceneManager()->setShadowTextureCasterMaterial(shadowMat);
108 
109  if (PSSM_Shadows.Quality == 3)
110  {
111  App::GetGfxScene()->GetSceneManager()->setShadowTextureConfig(0, 4096, 4096, PF_FLOAT32_R);
112  App::GetGfxScene()->GetSceneManager()->setShadowTextureConfig(1, 3072, 3072, PF_FLOAT32_R);
113  App::GetGfxScene()->GetSceneManager()->setShadowTextureConfig(2, 2048, 2048, PF_FLOAT32_R);
114  PSSM_Shadows.lambda = 0.965f;
115  }
116  else if (PSSM_Shadows.Quality == 2)
117  {
118  App::GetGfxScene()->GetSceneManager()->setShadowTextureConfig(0, 3072, 3072, PF_FLOAT32_R);
119  App::GetGfxScene()->GetSceneManager()->setShadowTextureConfig(1, 2048, 2048, PF_FLOAT32_R);
120  App::GetGfxScene()->GetSceneManager()->setShadowTextureConfig(2, 2048, 2048, PF_FLOAT32_R);
121  PSSM_Shadows.lambda = 0.97f;
122  }
123  else if (PSSM_Shadows.Quality == 1)
124  {
125  App::GetGfxScene()->GetSceneManager()->setShadowTextureConfig(0, 2048, 2048, PF_FLOAT32_R);
126  App::GetGfxScene()->GetSceneManager()->setShadowTextureConfig(1, 1024, 1024, PF_FLOAT32_R);
127  App::GetGfxScene()->GetSceneManager()->setShadowTextureConfig(2, 1024, 1024, PF_FLOAT32_R);
128  PSSM_Shadows.lambda = 0.975f;
129  }
130  else
131  {
132  App::GetGfxScene()->GetSceneManager()->setShadowTextureConfig(0, 1024, 1024, PF_FLOAT32_R);
133  App::GetGfxScene()->GetSceneManager()->setShadowTextureConfig(1, 1024, 1024, PF_FLOAT32_R);
134  App::GetGfxScene()->GetSceneManager()->setShadowTextureConfig(2, 512, 512, PF_FLOAT32_R);
135  PSSM_Shadows.lambda = 0.98f;
136  }
137 
138  if (PSSM_Shadows.mPSSMSetup.isNull())
139  {
140  // shadow camera setup
141  Ogre::PSSMShadowCameraSetup* pssmSetup = new Ogre::PSSMShadowCameraSetup();
142 
143  pssmSetup->calculateSplitPoints(3, App::GetCameraManager()->GetCamera()->getNearClipDistance(), App::GetGfxScene()->GetSceneManager()->getShadowFarDistance(), PSSM_Shadows.lambda);
144  pssmSetup->setSplitPadding(App::GetCameraManager()->GetCamera()->getNearClipDistance());
145 
146  pssmSetup->setOptimalAdjustFactor(0, -1);
147  pssmSetup->setOptimalAdjustFactor(1, -1);
148  pssmSetup->setOptimalAdjustFactor(2, -1);
149 
150  PSSM_Shadows.mPSSMSetup.bind(pssmSetup);
151 
152  //Send split info to managed materials
153  setManagedMaterialSplitPoints(pssmSetup->getSplitPoints());
154  }
155  App::GetGfxScene()->GetSceneManager()->setShadowCameraSetup(PSSM_Shadows.mPSSMSetup);
156 }
157 
158 void ShadowManager::updatePSSM()
159 {
160  if (!PSSM_Shadows.mPSSMSetup.get())
161  return;
162  //Ugh what here?
163 }
164 
165 void ShadowManager::updateTerrainMaterial(Ogre::TerrainPSSMMaterialGenerator::SM2Profile* matProfile)
166 {
167  if (App::gfx_shadow_type->getEnum<GfxShadowType>() == GfxShadowType::PSSM)
168  {
169  Ogre::PSSMShadowCameraSetup* pssmSetup = static_cast<Ogre::PSSMShadowCameraSetup*>(PSSM_Shadows.mPSSMSetup.get());
170  matProfile->setReceiveDynamicShadowsDepth(true);
171  matProfile->setReceiveDynamicShadowsLowLod(false);
172  matProfile->setReceiveDynamicShadowsEnabled(true);
173  matProfile->setReceiveDynamicShadowsPSSM(pssmSetup);
174  matProfile->setLightmapEnabled(false);
175  }
176 }
177 
178 void ShadowManager::setManagedMaterialSplitPoints(Ogre::PSSMShadowCameraSetup::SplitPointList splitPointList)
179 {
180  Ogre::Vector4 splitPoints;
181 
182  for (int i = 0; i < 3; ++i)
183  splitPoints[i] = splitPointList[i];
184 
185  GpuSharedParametersPtr p = GpuProgramManager::getSingleton().getSharedParameters("pssm_params");
186  p->setNamedConstant("pssmSplitPoints", splitPoints);
187 }
RoR::App::GetCameraManager
CameraManager * GetCameraManager()
Definition: Application.cpp:275
RoR::App::gfx_shadow_type
CVar * gfx_shadow_type
Definition: Application.cpp:217
CameraManager.h
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setLightmapEnabled
void setLightmapEnabled(bool enabled)
Whether to support a light map over the terrain in the shader, if it's present (default true).
Definition: OgreTerrainPSSMMaterialGenerator.cpp:151
Actor.h
RoR::GfxScene::GetSceneManager
Ogre::SceneManager * GetSceneManager()
Definition: GfxScene.h:64
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setReceiveDynamicShadowsDepth
void setReceiveDynamicShadowsDepth(bool enabled)
Whether to use depth shadows (default false).
Definition: OgreTerrainPSSMMaterialGenerator.cpp:191
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setReceiveDynamicShadowsPSSM
void setReceiveDynamicShadowsPSSM(PSSMShadowCameraSetup *pssmSettings)
Whether to use PSSM support dynamic texture shadows, and if so the settings to use (default 0).
Definition: OgreTerrainPSSMMaterialGenerator.cpp:181
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setReceiveDynamicShadowsLowLod
void setReceiveDynamicShadowsLowLod(bool enabled)
Whether to use shadows on low LOD material rendering (when using composite map) (default false).
Definition: OgreTerrainPSSMMaterialGenerator.cpp:201
GfxScene.h
ShadowManager.h
RoR::App::gfx_shadow_quality
CVar * gfx_shadow_quality
Definition: Application.cpp:234
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setReceiveDynamicShadowsEnabled
void setReceiveDynamicShadowsEnabled(bool enabled)
Whether to support dynamic texture shadows received from other objects, on the terrain (default true)...
Definition: OgreTerrainPSSMMaterialGenerator.cpp:171
Ogre
Definition: ExtinguishableFireAffector.cpp:35
RoR::CVar::getInt
int getInt() const
Definition: CVar.h:97
Ogre::TerrainPSSMMaterialGenerator::SM2Profile
Shader model 2 profile target.
Definition: OgreTerrainPSSMMaterialGenerator.h:52
RoR
Definition: AppContext.h:36
RoR::App::GetGfxScene
GfxScene * GetGfxScene()
Definition: Application.cpp:276