21 #include "CaelumPrecompiled.h" 22 #include "CaelumExceptions.h" 23 #include "DepthComposer.h" 29 DepthComposer::DepthComposer
31 Ogre::SceneManager *sceneMgr
34 mDebugDepthRender (false),
35 mSkyDomeHazeEnabled (false),
36 mGroundFogEnabled (false),
37 mGroundFogDensity (0.1),
38 mGroundFogBaseLevel (5),
39 mGroundFogVerticalDecay (0.2),
40 mGroundFogColour (ColourValue::Black)
44 DepthComposer::~DepthComposer()
46 destroyAllViewportInstances();
51 if (mDebugDepthRender == value) {
54 mDebugDepthRender = value;
55 onCompositorMaterialChanged ();
60 if (mSkyDomeHazeEnabled == value) {
63 mSkyDomeHazeEnabled = value;
64 onCompositorMaterialChanged ();
69 if (mGroundFogEnabled == value) {
72 mGroundFogEnabled = value;
73 onCompositorMaterialChanged ();
76 const String& DepthComposer::getCompositorName ()
79 static const Ogre::String CompositorName_DebugDepthRender =
80 "Caelum/DepthComposer_DebugDepthRender";
81 static const Ogre::String CompositorName_Dummy =
82 "Caelum/DepthComposer_Dummy";
83 static const Ogre::String CompositorName_ExpGroundFog =
84 "Caelum/DepthComposer_ExpGroundFog";
85 static const Ogre::String CompositorName_SkyDomeHaze =
86 "Caelum/DepthComposer_SkyDomeHaze";
87 static const Ogre::String CompositorName_SkyDomeHaze_ExpGroundFog =
88 "Caelum/DepthComposer_SkyDomeHaze_ExpGroundFog";
91 if (mDebugDepthRender) {
92 return CompositorName_DebugDepthRender;
93 }
else if (mSkyDomeHazeEnabled ==
false && mGroundFogEnabled ==
false) {
94 return CompositorName_Dummy;
95 }
else if (mSkyDomeHazeEnabled ==
false && mGroundFogEnabled ==
true) {
96 return CompositorName_ExpGroundFog;
97 }
else if (mSkyDomeHazeEnabled ==
true && mGroundFogEnabled ==
false) {
98 return CompositorName_SkyDomeHaze;
99 }
else if (mSkyDomeHazeEnabled ==
true && mGroundFogEnabled ==
true) {
100 return CompositorName_SkyDomeHaze_ExpGroundFog;
103 return CompositorName_Dummy;
107 void DepthComposer::onCompositorMaterialChanged ()
109 ViewportInstanceMap::const_iterator it;
110 ViewportInstanceMap::const_iterator begin = mViewportInstanceMap.begin();
111 ViewportInstanceMap::const_iterator end = mViewportInstanceMap.end();
112 for (it = begin; it != end; ++it) {
113 it->second->removeCompositor ();
114 it->second->addCompositor ();
118 void DepthComposer::update ()
120 ViewportInstanceMap::const_iterator it;
121 ViewportInstanceMap::const_iterator begin = mViewportInstanceMap.begin();
122 ViewportInstanceMap::const_iterator end = mViewportInstanceMap.end();
123 for (it = begin; it != end; ++it) {
124 assert(it->first == it->second->getViewport());
125 it->second->_update ();
129 DepthComposerInstance::DepthComposerInstance
132 Ogre::Viewport* viewport
138 LogManager::getSingleton().logMessage (
139 "Caelum::DepthComposer: Attaching screen-space fog instance" 140 " to viewport \'" + StringConverter::toString ((
long)getViewport ()) +
"\'" 141 " of render target \'" + getViewport()->getTarget ()->getName () +
"\'");
147 DepthComposerInstance::~DepthComposerInstance()
150 mDepthRenderer.reset ();
152 LogManager::getSingleton().logMessage (
153 "Caelum::DepthComposer: Detached screen-space fog instance" 154 " from viewport \'" + StringConverter::toString ((
long)getViewport ()) +
"\'" 155 " of render target \'" + getViewport()->getTarget ()->getName () +
"\'");
158 void DepthComposerInstance::addCompositor ()
160 CompositorManager* compMgr = CompositorManager::getSingletonPtr();
162 const String& compositorName = getParent ()->getCompositorName ();
163 mCompInst = compMgr->addCompositor(mViewport, compositorName);
165 CAELUM_THROW_UNSUPPORTED_EXCEPTION (
166 "Can't add \'" + compositorName +
"\' compositor.",
170 mCompInst->setEnabled (
true);
171 mCompInst->addListener (
this);
174 void DepthComposerInstance::removeCompositor ()
176 CompositorManager* compMgr = CompositorManager::getSingletonPtr();
177 compMgr->removeCompositor (mViewport, mCompInst->getCompositor ()->getName ());
181 void DepthComposerInstance::notifyMaterialSetup(uint pass_id, Ogre::MaterialPtr &mat)
186 Pass* pass = mat->getBestTechnique ()->getPass (0);
188 TextureUnitState *depthTus = pass->getTextureUnitState(1);
189 if (depthTus->getTextureName () != mDepthRenderer->getDepthRenderTexture ()->getName()) {
190 depthTus->setTextureName (mDepthRenderer->getDepthRenderTexture ()->getName ());
191 LogManager::getSingleton ().logMessage (
192 "Caelum::DepthComposer: Assigned depth texture in compositor material");
195 mParams.setup(pass->getFragmentProgramParameters ());
198 void DepthComposerInstance::Params::setup(Ogre::GpuProgramParametersSharedPtr fpParams)
200 this->fpParams = fpParams;
201 invViewProjMatrix.bind(fpParams,
"invViewProjMatrix");
202 worldCameraPos.bind(fpParams,
"worldCameraPos");
203 groundFogDensity.bind(fpParams,
"groundFogDensity");
204 groundFogVerticalDecay.bind(fpParams,
"groundFogVerticalDecay");
205 groundFogBaseLevel.bind(fpParams,
"groundFogBaseLevel");
206 groundFogColour.bind(fpParams,
"groundFogColour");
207 sunDirection.bind(fpParams,
"sunDirection");
208 hazeColour.bind(fpParams,
"hazeColour");
211 void DepthComposerInstance::notifyMaterialRender(uint pass_id, Ogre::MaterialPtr &mat)
213 Camera* camera = getViewport ()->getCamera ();
215 assert(mParams.fpParams == mat->getBestTechnique ()->getPass (0)->getFragmentProgramParameters ());
220 Matrix4 projMatrix = camera->getProjectionMatrixWithRSDepth();
221 Matrix4 viewMatrix = camera->getViewMatrix();
223 mParams.invViewProjMatrix.set(mParams.fpParams, (projMatrix * viewMatrix).inverse());
225 mParams.worldCameraPos.set(mParams.fpParams, camera->getDerivedPosition ());
227 mParams.groundFogDensity.set(mParams.fpParams, getParent ()->getGroundFogDensity ());
228 mParams.groundFogVerticalDecay.set(mParams.fpParams, getParent ()->getGroundFogVerticalDecay ());
229 mParams.groundFogBaseLevel.set(mParams.fpParams, getParent ()->getGroundFogBaseLevel ());
230 mParams.groundFogColour.set(mParams.fpParams, getParent ()->getGroundFogColour ());
232 mParams.sunDirection.set(mParams.fpParams, getParent ()->getSunDirection ());
233 mParams.hazeColour.set(mParams.fpParams, getParent ()->getHazeColour ());
238 mDepthRenderer->update ();
243 ViewportInstanceMap::const_iterator it = mViewportInstanceMap.find(vp);
244 if (it == mViewportInstanceMap.end()) {
246 mViewportInstanceMap.insert(std::make_pair(vp, inst.get()));
248 return inst.release();
255 ViewportInstanceMap::iterator it = mViewportInstanceMap.find(vp);
256 if (it != mViewportInstanceMap.end()) {
263 void DepthComposer::destroyViewportInstance(Viewport* vp)
265 ViewportInstanceMap::iterator it = mViewportInstanceMap.find(vp);
266 if (it != mViewportInstanceMap.end()) {
269 mViewportInstanceMap.erase(it);
273 void DepthComposer::destroyAllViewportInstances() {
274 ViewportInstanceMap::const_iterator it;
275 ViewportInstanceMap::const_iterator begin = mViewportInstanceMap.begin();
276 ViewportInstanceMap::const_iterator end = mViewportInstanceMap.end();
277 for (it = begin; it != end; ++it) {
278 assert(it->first == it->second->getViewport());
281 mViewportInstanceMap.clear();
286 DepthRenderer::DepthRenderer
288 Viewport* masterViewport
290 mMasterViewport (masterViewport),
291 mDepthRenderViewport (0),
292 mDepthRenderingNow (
false),
293 mViewportVisibilityMask (~0),
294 mUseCustomDepthScheme (
true),
295 mCustomDepthSchemeName (DEFAULT_CUSTOM_DEPTH_SCHEME_NAME)
297 disableRenderGroupRangeFilter ();
299 Ogre::String uniqueId = Ogre::StringConverter::toString ((
size_t)
this);
302 mDepthRenderMaterial = MaterialManager::getSingleton ().getByName (
"Caelum/DepthRender");
303 mDepthRenderMaterial->load();
304 if (!mDepthRenderMaterial->getBestTechnique ()) {
305 CAELUM_THROW_UNSUPPORTED_EXCEPTION (
306 "Can't load depth render material: " +
307 mDepthRenderMaterial->getUnsupportedTechniquesExplanation(),
311 TextureManager* texMgr = TextureManager::getSingletonPtr();
313 int width = getMasterViewport ()->getActualWidth ();
314 int height = getMasterViewport ()->getActualHeight ();
315 LogManager::getSingleton ().logMessage (
316 "Caelum::DepthRenderer: Creating depth render texture size " +
317 StringConverter::toString (width) +
319 StringConverter::toString (height));
321 PixelFormat desiredFormat = PF_FLOAT32_R;
322 PixelFormat requestFormat = desiredFormat;
323 if (texMgr->isFormatSupported (TEX_TYPE_2D, desiredFormat, TU_RENDERTARGET)) {
324 LogManager::getSingleton ().logMessage (
325 "Caelum::DepthRenderer: RenderSystem has native support for " +
326 PixelUtil::getFormatName (desiredFormat));
327 }
else if (texMgr->isEquivalentFormatSupported (TEX_TYPE_2D, desiredFormat, TU_RENDERTARGET)) {
328 PixelFormat equivFormat = texMgr->getNativeFormat (TEX_TYPE_2D, desiredFormat, TU_RENDERTARGET);
329 LogManager::getSingleton ().logMessage (
330 "Caelum::DepthRenderer: RenderSystem supports " +
331 PixelUtil::getFormatName (equivFormat) +
333 PixelUtil::getFormatName (desiredFormat));
334 requestFormat = equivFormat;
336 CAELUM_THROW_UNSUPPORTED_EXCEPTION (
337 PixelUtil::getFormatName(desiredFormat) +
" or equivalent not supported",
341 if (texMgr->isHardwareFilteringSupported (TEX_TYPE_2D, requestFormat, TU_RENDERTARGET)) {
342 LogManager::getSingleton ().logMessage (
343 "Caelum::DepthRenderer: RenderSystem supports hardware filtering for " +
344 PixelUtil::getFormatName (requestFormat));
346 LogManager::getSingleton ().logMessage (
347 "Caelum::DepthRenderer: RenderSystem does not support hardware filtering for " +
348 PixelUtil::getFormatName (requestFormat));
353 mDepthRenderTexture = texMgr->createManual(
354 "Caelum/DepthComposer/" + uniqueId +
"/DepthTexture",
363 assert(getDepthRenderTarget());
366 LogManager::getSingleton().logMessage (
367 "Caelum::DepthRenderer: Created depth render texture" 368 " actual format " + PixelUtil::getFormatName (getDepthRenderTexture()->getFormat ()) +
369 " desired format " + PixelUtil::getFormatName (getDepthRenderTexture()->getDesiredFormat ()));
372 getDepthRenderTarget()->setAutoUpdated (
false);
375 mDepthRenderViewport = getDepthRenderTarget()->addViewport(0);
376 getDepthRenderViewport ()->setShadowsEnabled (
false);
377 getDepthRenderViewport ()->setOverlaysEnabled (
false);
378 getDepthRenderViewport ()->setClearEveryFrame (
true);
382 getDepthRenderViewport ()->setBackgroundColour (Ogre::ColourValue (1, 1, 1, 1));
385 DepthRenderer::~DepthRenderer()
387 TextureManager* texMgr = TextureManager::getSingletonPtr();
390 if (!mDepthRenderTexture.isNull ()) {
391 texMgr->remove (mDepthRenderTexture->getHandle ());
392 mDepthRenderTexture.setNull ();
398 Camera* camera = getMasterViewport ()->getCamera ();
399 Viewport* oldCameraViewport = camera->getViewport ();
400 SceneManager *sceneManager = camera->getSceneManager ();
402 assert (oldCameraViewport == getMasterViewport ());
403 assert (getDepthRenderViewport ()->getActualWidth () == getMasterViewport()->getActualWidth ());
404 assert (getDepthRenderViewport ()->getActualHeight () == getMasterViewport()->getActualHeight ());
406 getDepthRenderViewport ()->setVisibilityMask (mViewportVisibilityMask);
407 getDepthRenderViewport ()->setCamera (camera);
408 if (this->getUseCustomDepthScheme ()) {
409 getDepthRenderViewport ()->setMaterialScheme (this->getCustomDepthSchemeName ());
414 RenderQueue::RenderableListener* oldListener = sceneManager->getRenderQueue ()->getRenderableListener();
419 sceneManager->getRenderQueue ()->setRenderableListener (
this);
421 mDepthRenderingNow =
true;
423 getDepthRenderTarget ()->update ();
425 mDepthRenderingNow =
false;
427 sceneManager->getRenderQueue ()->setRenderableListener (oldListener);
431 camera->_notifyViewport (oldCameraViewport);
434 #if OGRE_VERSION < 0x00010600 435 bool DepthRenderer::renderableQueued(
436 Ogre::Renderable* rend,
438 Ogre::ushort priority,
439 Ogre::Technique** ppTech)
441 bool DepthRenderer::renderableQueued(
442 Ogre::Renderable* rend,
444 Ogre::ushort priority,
445 Ogre::Technique** ppTech,
446 Ogre::RenderQueue* pQueue)
447 #endif // OGRE_VERSION 449 assert (mDepthRenderingNow);
457 if (groupId < mMinRenderGroupId || groupId > mMaxRenderGroupId) {
461 if (this->getUseCustomDepthScheme () && (*ppTech)->getSchemeName () == this->getCustomDepthSchemeName ()) {
473 Material* depthMaterial = getDepthRenderMaterial ();
474 Technique* tech = depthMaterial->getBestTechnique ();
483 mMinRenderGroupId = minGroup;
484 mMaxRenderGroupId = maxGroup;
489 setRenderGroupRangeFilter(Ogre::RENDER_QUEUE_BACKGROUND, Ogre::RENDER_QUEUE_MAX);
void disableRenderGroupRangeFilter()
Disable the effects of.
Compositor-based precipitation controller.
void setDebugDepthRender(bool value)
Enables drawing the depth buffer.
Per-viewport instance of.
static const String DEFAULT_CUSTOM_DEPTH_SCHEME_NAME
Default name of the custom scheme.
void setGroundFogEnabled(bool value)
Enables exponential ground fog.
void _update()
Called from DepthComposer::update.
static const String RESOURCE_GROUP_NAME
Resource group name for caelum resources.
Render the depth buffer to a texture.
void setRenderGroupRangeFilter(int minGroup, int maxGroup)
Render only the render groups in a certain range.
void setSkyDomeHazeEnabled(bool value)
Enables skydome haze.
void update()
Render the depth buffer now!