16#include <OgreDepthBuffer.h>
21 SDynamicReflectionMap::SDynamicReflectionMap() : SNode(0,
"", SNode::DYNAMIC_REFLECTION_MAP_ID)
26 SDynamicReflectionMap::SDynamicReflectionMap(
SScene* parent,
SViewPort* viewport,
const std::string& dynamicReflectionMapName) :
SNode(parent, dynamicReflectionMapName,
SNode::DYNAMIC_REFLECTION_MAP_ID)
29 reflectionMapScheme = dynamicReflectionMapName +
"_SO3_DynamicReflectionMap_Scheme";
32 revertClipPlane =
false;
33 needTextureUpdate =
false;
35 renderingEnable =
false;
36 flipClipPlane =
false;
41 reflectionMapTargets = 0;
42 reflectionMapViewport = viewport;
45 reflectionMapPlane =
new Ogre::MovablePlane(
"reflectionPlane" + reflectionMapScheme);
46 reflectionMapPlane->redefine(Ogre::Vector3::UNIT_Y, Ogre::Vector3::ZERO);
48 reflectionMapPlane->setVisible(
false);
49 reflectionMapPlane->normal = Ogre::Vector3::UNIT_Y;
52 cameraClipPlane =
new Ogre::MovablePlane(
"CameraClipPlane" + reflectionMapScheme);
53 cameraClipPlane->redefine(Ogre::Vector3::UNIT_Y, Ogre::Vector3::ZERO);
55 cameraClipPlane->normal = Ogre::Vector3::UNIT_Y;
56 cameraClipPlane->setVisible(
false);
61 camNode->attachObject(reflectionMapCamera);
64 reflectionMapCamera->setFOVy(Ogre::Degree(45));
65 reflectionMapCamera->setAspectRatio(1);
66 reflectionMapCamera->setNearClipDistance(Ogre::Real(0.001));
69 reflectionMapCamera->enableReflection(reflectionMapPlane);
72 reflectionMapCamera->enableCustomNearClipPlane(cameraClipPlane);
75 _CreateReflectionMapTexture(size);
78 materialTransparent = Ogre::MaterialManager::getSingleton().create(
"SO3_Material_" + reflectionMapScheme, SO3_INTERNAL_DYNAMIC_RESOURCE_GROUP);
79 materialTransparent->getTechnique(0)->setColourWriteEnabled(
false);
80 materialTransparent->getTechnique(0)->setDepthCheckEnabled(
false);
81 materialTransparent->getTechnique(0)->setDepthWriteEnabled(
false);
82 materialTransparent->getTechnique(0)->getPass(0)->setName(
"SO3/TRANSPARENT/REFMAP");
83 materialTransparent->getTechnique(0)->getPass(0)->setVertexProgram(
"SO3/Internal/Default_nolight_vp");
84 materialTransparent->getTechnique(0)->getPass(0)->setFragmentProgram(
"SO3/Internal/Default_fp");
85 materialTransparent->load();
94 _DeleteReflectionMapTexture();
100 Ogre::MaterialManager::getSingleton().remove(materialTransparent->getHandle());
101 materialTransparent.reset();
102 reflectionMapCamera->disableCustomNearClipPlane();
103 reflectionMapCamera->disableReflection();
109 SO3_SAFE_DELETE(reflectionMapPlane);
112 SO3_SAFE_DELETE(cameraClipPlane);
120 double result = log((
double)newSize) / log((
double)2.0);
121 double fractpart, intpart;
122 fractpart = modf(result, &intpart);
125 bool savedState = state;
130 _CreateReflectionMapTexture(newSize);
137 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS,
"Reflection map texture size must be a power of 2 number!",
"SDynamicReflectionMap::SetSize");
149 if (targetMaterial != 0)
151 bool savedState = state;
155 techIndex = targetTechnique;
156 passIndex = targetPass;
157 unitIndex = targetTextureUnit;
166 void SDynamicReflectionMap::SetTextureUnit()
171 Ogre::Material::Techniques suptechs = material->getSupportedTechniques();
172 Ogre::Material::Techniques techs = material->getTechniques();
174 if (techIndex >= techs.size() || (suptechs.size() == 0))
177 Ogre::Technique::Passes matPasses;
178 Ogre::Pass* tmpPass = 0;
180 if (caps && caps->hasCapability(Ogre::RSC_FIXED_FUNCTION) ==
false)
182 matPasses = suptechs[0]->getPasses();
183 if (passIndex >= matPasses.size())
186 tmpPass = matPasses[passIndex];
190 matPasses = techs[techIndex]->getPasses();
191 if (techIndex >= matPasses.size())
194 tmpPass = matPasses[techIndex];
198 Ogre::TextureUnitState* texState = 0;
199 Ogre::Pass::TextureUnitStates texs = tmpPass->getTextureUnitStates();
200 if ((texs.size() > 0) && (unitIndex < texs.size()))
201 texState = texs[unitIndex];
205 oldTexture = texState->_getTexturePtr();
206 oldTextureType = texState->getTextureType();
207 oldAdressingMode = texState->getTextureAddressingMode();
209 Ogre::TextureUnitState::EffectMap effects = texState->getEffects();
210 Ogre::TextureUnitState::EffectMap::iterator ei = effects.find(Ogre::TextureUnitState::ET_ENVIRONMENT_MAP);
211 oldTextureEnvState = ei != effects.end();
213 if (oldTextureEnvState)
214 oldTextureEnvType = (Ogre::TextureUnitState::EnvMapType)ei->second.subtype;
216 texState->setTexture(reflectionMapTexture);
217 texState->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
218 texState->setEnvironmentMap(
false);
219 texState->setProjectiveTexturing(
true, reflectionMapCamera);
221 Ogre::Any bindedSPass = tmpPass->getUserObjectBindings().getUserAny(
"SPass");
222 if (bindedSPass.has_value())
224 SPass* pass = Ogre::any_cast<SPass*> (bindedSPass);
232 void SDynamicReflectionMap::ResetTextureUnit()
234 Ogre::Material::Techniques suptechs = material->getSupportedTechniques();
235 Ogre::Material::Techniques techs = material->getTechniques();
237 if (techIndex >= techs.size() || (suptechs.size() == 0))
240 Ogre::Technique::Passes matPasses;
241 Ogre::Pass* tmpPass = 0;
243 if (caps && caps->hasCapability(Ogre::RSC_FIXED_FUNCTION) ==
false)
245 matPasses = suptechs[0]->getPasses();
246 if (passIndex >= matPasses.size())
249 tmpPass = matPasses[passIndex];
253 matPasses = techs[techIndex]->getPasses();
254 if (techIndex >= matPasses.size())
257 tmpPass = matPasses[techIndex];
261 Ogre::TextureUnitState* texState = 0;
262 Ogre::Pass::TextureUnitStates texs = tmpPass->getTextureUnitStates();
263 if ((texs.size() > 0) && (unitIndex < texs.size()))
264 texState = texs[unitIndex];
268 texState->setProjectiveTexturing(
false);
269 texState->setTextureAddressingMode(oldAdressingMode);
271 if (oldTextureEnvState)
272 texState->setEnvironmentMap(oldTextureEnvState, oldTextureEnvType);
275 texState->setBlank();
277 texState->setTexture(oldTexture);
279 Ogre::Any bindedSPass = tmpPass->getUserObjectBindings().getUserAny(
"SPass");
280 if (bindedSPass.has_value())
282 SPass* pass = Ogre::any_cast<SPass*> (bindedSPass);
293 if (reflectionMapTexture)
298 if ((newState ==
true) && (state ==
false))
304 else if ((newState ==
false) && (state ==
true))
320 if (newFlip != flipClipPlane)
322 flipClipPlane = newFlip;
325 reflectionMapCamera->disableCustomNearClipPlane();
326 reflectionMapCamera->disableReflection();
330 SO3_SAFE_DELETE(cameraClipPlane);
334 SO3_SAFE_DELETE(reflectionMapPlane);
337 cameraClipPlane =
new Ogre::MovablePlane(
"CameraClipPlane" + reflectionMapScheme);
338 cameraClipPlane->redefine(((flipClipPlane && !revertClipPlane) || (revertClipPlane && !flipClipPlane)) ? Ogre::Vector3::NEGATIVE_UNIT_Y : Ogre::Vector3::UNIT_Y, Ogre::Vector3::ZERO);
341 cameraClipPlane->normal = Ogre::Vector3::UNIT_Y;
342 cameraClipPlane->setVisible(
false);
345 reflectionMapPlane =
new Ogre::MovablePlane(
"reflectionPlane" + reflectionMapScheme);
346 reflectionMapPlane->redefine(flipClipPlane ? (Ogre::Vector3::NEGATIVE_UNIT_Y) : (Ogre::Vector3::UNIT_Y), Ogre::Vector3::ZERO);
349 reflectionMapPlane->normal = Ogre::Vector3::UNIT_Y;
350 reflectionMapPlane->setVisible(
false);
353 reflectionMapCamera->enableCustomNearClipPlane(cameraClipPlane);
356 if (!revertClipPlane)
357 reflectionMapCamera->enableReflection(reflectionMapPlane);
363 if (newRevertClipPlaneValue != revertClipPlane)
365 revertClipPlane = newRevertClipPlaneValue;
368 reflectionMapCamera->disableCustomNearClipPlane();
372 SO3_SAFE_DELETE(cameraClipPlane);
375 cameraClipPlane =
new Ogre::MovablePlane(
"CameraClipPlane" + reflectionMapScheme);
376 cameraClipPlane->redefine(revertClipPlane ? -Ogre::Vector3::UNIT_Y : Ogre::Vector3::UNIT_Y, Ogre::Vector3::ZERO);
378 cameraClipPlane->setVisible(
false);
381 reflectionMapCamera->enableCustomNearClipPlane(cameraClipPlane);
385 reflectionMapCamera->disableReflection();
387 reflectionMapCamera->enableReflection(reflectionMapPlane);
393 return revertClipPlane;
397 void SDynamicReflectionMap::EnableRendering()
399 if (!renderingEnable)
401 reflectionMapTargets->addListener(
this);
402 reflectionMapTargets->setAutoUpdated(
true);
405 renderingEnable =
true;
409 void SDynamicReflectionMap::DisableRendering()
413 reflectionMapTargets->removeListener(
this);
414 reflectionMapTargets->setAutoUpdated(
false);
417 renderingEnable =
false;
421 void SDynamicReflectionMap::_CreateReflectionMapTexture(
const unsigned int& newSize)
423 _DeleteReflectionMapTexture();
426 Ogre::PixelFormat rttformat;
429 reflectionMapTexture = Ogre::TextureManager::getSingleton().createManual(
"texture_" + reflectionMapScheme, SO3_INTERNAL_DYNAMIC_READABLE_RESOURCE_GROUP, Ogre::TEX_TYPE_2D, newSize, newSize, Ogre::MIP_DEFAULT, rttformat, Ogre::TU_RENDERTARGET | Ogre::TU_AUTOMIPMAP);
430 reflectionMapTargets = reflectionMapTexture->getBuffer()->getRenderTarget();
433 reflectionMapTargets->setDepthBufferPool(Ogre::DepthBuffer::POOL_NO_DEPTH);
436 Ogre::Viewport* viewport = reflectionMapTargets->addViewport(reflectionMapCamera);
437 viewport->setOverlaysEnabled(
false);
438 viewport->setMaterialScheme(reflectionMapScheme);
440 catch (Ogre::Exception &e)
442 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage(
"An exception has occurred: " + e.getDescription());
443 reflectionMapTexture.reset();
447 void SDynamicReflectionMap::_DeleteReflectionMapTexture()
449 if (reflectionMapTexture)
452 if (reflectionMapTargets)
454 reflectionMapTargets->removeAllViewports();
455 Ogre::Root::getSingleton().detachRenderTarget(reflectionMapTargets);
456 reflectionMapTargets = 0;
459 Ogre::TextureManager::getSingleton().remove(reflectionMapTexture->getHandle());
460 reflectionMapTexture.reset();
466 if (needTextureUpdate)
468 _CreateReflectionMapTexture(size);
469 needTextureUpdate =
false;
500 Ogre::Material::Techniques suptechs = materialTransparent->getTechniques();
501 if ((reflectionMapScheme == schemeName) && (originalMaterial == material.get()) && (suptechs.size() > 0))
Ogre::Camera * GetOgreCameraPointer()
float GetNearClipDistance()
const Ogre::Matrix4 & GetProjectionMatrix()
float GetFarClipDistance()
void SetSize(const unsigned int &newSize)
virtual Ogre::Technique * handleSchemeNotFound(unsigned short schemeIndex, const Ogre::String &schemeName, Ogre::Material *originalMaterial, unsigned short lodIndex, const Ogre::Renderable *rend)
void SetRevertClipPlane(const bool &newRevertClipPlaneValue)
void FlipPlane(const bool &newFlip)
virtual void postRenderTargetUpdate(const Ogre::RenderTargetEvent &evt)
void SetEnable(const bool &newState)
void SetMaterial(SMaterial *targetMaterial, const int &targetTechnique, const int &targetPass, const int &targetTextureUnit)
virtual void preRenderTargetUpdate(const Ogre::RenderTargetEvent &evt)
bool GetRevertClipPlane()
Ogre::MaterialPtr getOgreMaterialPointer()
virtual Ogre::Quaternion GetGlobalOrientation()
Ogre::SceneNode * O3SceneNode
virtual Ogre::Vector3 GetGlobalPosition()
virtual Ogre::Matrix4 GetTransformationMatrix()
bool GetRttPixelFormat(Ogre::PixelFormat &format, bool alpha=false, bool floattex=false)
Ogre::RenderSystem * GetOgreRenderSystem()
void RemoveGeneratedMaterial(Ogre::Material *mat)
static SRoot & getSingleton()
static SRoot * getSingletonPtr()
Ogre::SceneManager * GetOgreScenePointer()