DeferredLightCP.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2015 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 #ifndef _DEFERRED_LIGHT_CP_HH_
18 #define _DEFERRED_LIGHT_CP_HH_
19 
20 #include <OgreCompositorInstance.h>
21 #include <OgreCustomCompositionPass.h>
22 
23 #include <map>
24 #include <vector>
25 
31 #include "gazebo/util/system.hh"
32 
33 namespace gazebo
34 {
35  namespace rendering
36  {
41  template<typename techniquePolicy>
43  : public Ogre::CompositorInstance::RenderSystemOperation,
44  public techniquePolicy
45  {
46  public: DeferredLightRenderOperation(Ogre::CompositorInstance *_instance,
47  const Ogre::CompositionPass *_pass)
48  {
49  this->viewport = _instance->getChain()->getViewport();
50 
52  for (int i = 0; i < this->GetGBufferSize(); ++i)
53  {
54  const Ogre::CompositionPass::InputTex &input = _pass->getInput(i);
55  this->inputTexNames.push_back(
56  _instance->getTextureInstanceName(input.name, input.mrtIndex));
57  }
58 
59  // Create lights material generator
60  this->lightMaterialGenerator =
62 
63  // Create the ambient light
64  this->ambientLight = new AmbientLight<techniquePolicy>();
65  const Ogre::MaterialPtr &mat = this->ambientLight->getMaterial();
66  mat->load();
67  this->instanceManager = NULL;
68  this->rsmActive = false;
69  }
70 
72  public: virtual void execute(Ogre::SceneManager *_sm,
73  Ogre::RenderSystem * /*_rs*/)
74  {
75  if (!this->instanceManager)
76  {
77  this->instanceManager = _sm->getInstanceManager("VPL_InstanceMgr");
78  }
79 
80  Ogre::Camera *cam = this->viewport->getCamera();
81  Ogre::Technique *tech;
82 
83  // Update the ambient light based on the camera
84  this->ambientLight->UpdateFromCamera(cam);
85 
86  tech = this->ambientLight->getMaterial()->getBestTechnique();
87  InjectTechnique(_sm, tech, this->ambientLight, 0);
88 
89  // TODO: Improve this.
90  bool findVisible = _sm->getFindVisibleObjects();
91  _sm->setFindVisibleObjects(true);
92 
93  const Ogre::LightList &lightList = _sm->_getLightsAffectingFrustum();
94  for (Ogre::LightList::const_iterator it = lightList.begin();
95  it != lightList.end(); ++it)
96  {
97  Ogre::Light *light = *it;
98  Ogre::LightList ll;
99  ll.push_back(light);
100 
101  LightsMap::iterator dLightIt = this->lights.find(light);
102  DeferredLight* dLight = 0;
103  if (dLightIt == this->lights.end())
104  {
105  dLight = this->CreateDeferredLight(light);
106  if (dLight->getCastShadows())
107  {
108  dLight->SetVPLCount(400, _sm, this->instanceManager);
109  }
110  }
111  else
112  {
113  dLight = dLightIt->second;
114  dLight->UpdateFromParent();
115  }
116 
117  dLight->UpdateFromCamera(cam);
118  tech = dLight->getMaterial()->getBestTechnique();
119 
120  // Update shadow texture
121  if (dLight->getCastShadows())
122  {
123  Ogre::SceneManager::RenderContext *context = _sm->_pauseRendering();
124 
125  _sm->prepareShadowTextures(cam, this->viewport, &ll);
126  _sm->_resumeRendering(context);
127 
128  const Ogre::TexturePtr &shadowTex = _sm->getShadowTexture(0);
129  dLight->UpdateRSM(shadowTex);
130 
131  Ogre::ShadowCameraSetupPtr cameraSetup =
132  dLight->GetParentLight()->getCustomShadowCameraSetup();
133  if (cameraSetup.isNull())
134  {
135  cameraSetup = _sm->getShadowCameraSetup();
136  }
137 
138  /*Ogre::Camera shadowCam("temp_shadow_cam", _sm);
139  shadowCam.setAspectRatio(1.0);
140 
141  cameraSetup->getShadowCamera(_sm, cam, this->viewport,
142  dLight->GetParentLight(), &shadowCam, 0);
143  Ogre::Matrix4 proj = shadowCam.getProjectionMatrix();
144  Ogre::Matrix4 view = shadowCam.getViewMatrix();
145  proj = proj*view;
146  Ogre::Matrix4 invProj = proj.inverse();
147  dLight->UpdateShadowInvProj(invProj);
148  */
149 
150  if (this->rsmActive)
151  {
152  dLight->RenderVPLs(_sm, this->instanceManager);
153  }
154 
155  Ogre::Pass *pass = tech->getPass(0);
156  Ogre::TextureUnitState *tus =
157  pass->getTextureUnitState("ShadowMap");
158 
159  if (!tus)
160  gzthrow("Invalid texture unit state");
161 
162  if (tus->_getTexturePtr() != shadowTex)
163  tus->_setTexturePtr(shadowTex);
164  }
165  else
166  printf("NO SHADOWS\n");
167 
168  InjectTechnique(_sm, tech, dLight, &ll);
169  }
170 
171  // restore previous settings
172  _sm->setFindVisibleObjects(findVisible);
173  }
174 
176  {
177  for (LightsMap::iterator it = this->lights.begin();
178  it != this->lights.end(); ++it)
179  {
180  delete it->second;
181  }
182  this->lights.clear();
183 
184  delete this->ambientLight;
185  delete this->lightMaterialGenerator;
186  }
187 
189  private: DeferredLight *CreateDeferredLight(Ogre::Light *_light)
190  {
191  DeferredLight *rv = new DeferredLight(this->lightMaterialGenerator,
192  _light, Ogre::MaterialManager::getSingleton().getByName(
193  this->GetMaterialPrefix()+"/VPL"));
194  this->lights[_light] = rv;
195  return rv;
196  }
197 
198  private: void InjectTechnique(Ogre::SceneManager *_sm,
199  Ogre::Technique *_tech, Ogre::Renderable *_rend,
200  const Ogre::LightList *_lightList)
201  {
202  for (uint16_t i = 0; i < _tech->getNumPasses(); ++i)
203  {
204  Ogre::Pass *pass = _tech->getPass(i);
205 
206  if (_lightList != 0)
207  _sm->_injectRenderWithPass(pass, _rend, false, false, _lightList);
208  else
209  _sm->_injectRenderWithPass(pass, _rend, false);
210  }
211  }
212 
214  private: std::vector<Ogre::String> inputTexNames;
215 
217  private: MaterialGenerator *lightMaterialGenerator;
218 
220  private: typedef std::map<Ogre::Light*, DeferredLight*> LightsMap;
221  private: LightsMap lights;
222 
224  private: AmbientLight<techniquePolicy> *ambientLight;
225 
227  private: Ogre::Viewport* viewport;
228 
229  private: Ogre::InstanceManager *instanceManager;
230  private: bool rsmActive;
231  };
232 
235  template<typename techniquePolicy>
237  : public Ogre::CustomCompositionPass, public techniquePolicy
238  {
240  public: virtual Ogre::CompositorInstance::RenderSystemOperation
241  *createOperation(Ogre::CompositorInstance *_instance,
242  const Ogre::CompositionPass *_pass)
243  {
245  _instance, _pass);
246  }
247 
248  protected: virtual ~DeferredLightCompositionPass() {}
249  };
250  }
251 }
252 #endif
void UpdateFromParent()
Update the information from the light that matches this one.
The custom composition pass that is used for rendering the light geometry.
Definition: DeferredLightCP.hh:236
#define gzthrow(msg)
This macro logs an error to the throw stream and throws an exception that contains the file name and ...
Definition: Exception.hh:39
Ogre::Light * GetParentLight()
Definition: DeferredLight.hh:66
virtual const Ogre::MaterialPtr & getMaterial(void) const
Definition: LightMaterialGenerator.hh:45
The render operation that will be called each frame in the custom composition pass This is the class ...
Definition: DeferredLightCP.hh:42
void UpdateFromCamera(Ogre::Camera *_camera)
Update the information that is related to the camera
Deferred light geometry.
Definition: DeferredLight.hh:34
virtual ~DeferredLightCompositionPass()
Definition: DeferredLightCP.hh:248
void SetVPLCount(uint32_t _n, Ogre::SceneManager *_sm, Ogre::InstanceManager *_im)
void RenderVPLs(Ogre::SceneManager *_sm, Ogre::InstanceManager *_im)
#define NULL
Definition: CommonTypes.hh:30
virtual void execute(Ogre::SceneManager *_sm, Ogre::RenderSystem *)
Definition: DeferredLightCP.hh:72
virtual ~DeferredLightRenderOperation()
Definition: DeferredLightCP.hh:175
virtual Ogre::CompositorInstance::RenderSystemOperation * createOperation(Ogre::CompositorInstance *_instance, const Ogre::CompositionPass *_pass)
Definition: DeferredLightCP.hh:241
Definition: AmbientLight.hh:38
#define GAZEBO_VISIBLE
Use to represent "symbol visible" if supported.
Definition: system.hh:48
DeferredLightRenderOperation(Ogre::CompositorInstance *_instance, const Ogre::CompositionPass *_pass)
Definition: DeferredLightCP.hh:46
virtual void UpdateRSM(const Ogre::TexturePtr &_shadowTex)
virtual bool getCastShadows() const
Does this light cast shadows?