37#include <OgreBitwise.h>
38#include <OgreDepthBuffer.h>
42SSubEntityCameraSelectorBuffer::SSubEntityCameraSelectorBuffer(Ogre::Camera* camera,
const std::string& name,
unsigned int texwidth,
unsigned int texheight,
bool useDepth)
45 mBaseResourceName = std::string(SO3_INTERNAL_SUBENTITY_SELECTOR_RESOURCE_GROUP) +
"/" + name;
48 if (rendererName ==
"Vulkan Rendering Subsystem")
52 Ogre::ResourceGroupManager::getSingleton().createResourceGroup(mBaseResourceName,
false);
55 mRenderPickerBuffer = 0;
57 mOgreRenderTexture = 0;
58 mOgreRenderDepthTexture = 0;
63 mTextureWidth = texwidth;
64 mTextureHeight = texheight;
65 mCompensateNPOT =
false;
69 mOgrePickerRenderTexture = 0;
71 mOgrePickerCamera = 0;
74 const Ogre::RenderSystemCapabilities* caps = ogreRenderSystem->getCapabilities();
75 if (mUseDepth && caps && !caps->hasCapability(Ogre::RSC_MRT_SAME_BIT_DEPTHS))
81 mPickerMat = Ogre::MaterialManager::getSingletonPtr()->getByName(
"SO3/Internal/EntitySelector/Material/MouseColor");
84 CreateTexture(texwidth, texheight);
91SSubEntityCameraSelectorBuffer::SSubEntityCameraSelectorBuffer()
101 Ogre::ResourceGroupManager::getSingleton().unloadResourceGroup(mBaseResourceName);
102 Ogre::ResourceGroupManager::getSingleton().clearResourceGroup(mBaseResourceName);
103 Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup(mBaseResourceName);
105 SO3_SAFE_DELETE(nodeSelectorMaterialSwitcher);
119 CreateTexture(mTextureWidth, mTextureHeight);
127 Ogre::PixelFormat rttpf = Ogre::PF_A8R8G8B8;
131 mOgrePickerTexture = Ogre::TextureManager::getSingleton().createManual(mBaseResourceName +
"/Picker", SO3_INTERNAL_SUBENTITY_SELECTOR_RESOURCE_GROUP, Ogre::TEX_TYPE_2D, 1, 1, 0, rttpf, Ogre::TU_RENDERTARGET);
132 mOgrePickerTexture->load();
134 catch (Ogre::Exception &e)
136 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage(
"An exception has occurred in SSubEntityCameraSelectorBuffer::CreatePicker : " + e.getDescription());
137 mOgrePickerTexture.reset();
140 if (mOgrePickerTexture)
143 Ogre::HardwarePixelBufferSharedPtr ogrePixelBuffer = mOgrePickerTexture->getBuffer();
144 mOgrePickerRenderTexture = ogrePixelBuffer->getRenderTarget();
145 mOgrePickerRenderTexture->setAutoUpdated(
false);
147#if defined(APPLE_IOS)
148 mOgrePickerRenderTexture->setDepthBufferPool(Ogre::DepthBuffer::POOL_NO_DEPTH);
152 size_t bufferSize = ogrePixelBuffer->getSizeInBytes();
153 mRenderPickerBuffer =
new Ogre::uint8[bufferSize];
154 mOgrePixelBox =
new Ogre::PixelBox(ogrePixelBuffer->getWidth(), ogrePixelBuffer->getHeight(), ogrePixelBuffer->getDepth(), ogrePixelBuffer->getFormat(), mRenderPickerBuffer);
157 mOgrePickerScene = Ogre::Root::getSingleton().createSceneManager(Ogre::SMT_DEFAULT, mBaseResourceName +
"/Picker/Scene");
159 Ogre::AxisAlignedBox octreeBox(-1, -1, -1, 1, 1, 1);
161 mOgrePickerScene->setOption(
"Size", &octreeBox);
162 mOgrePickerScene->setOption(
"Depth", &octreeDepth);
164 Ogre::RenderQueue* rq = mOgrePickerScene->getRenderQueue();
165 rq->getQueueGroup(Ogre::RENDER_QUEUE_WORLD_GEOMETRY_1)->setShadowsEnabled(
false);
166 rq->getQueueGroup(Ogre::RENDER_QUEUE_WORLD_GEOMETRY_2)->setShadowsEnabled(
false);
167 rq->getQueueGroup(Ogre::RENDER_QUEUE_MAIN)->setShadowsEnabled(
false);
168 rq->getQueueGroup(49)->setShadowsEnabled(
false);
171 mOgrePickerCamera = mOgrePickerScene->createCamera(mBaseResourceName +
"/Picker/Camera");
172 mOgrePickerScene->getRootSceneNode()->attachObject(mOgrePickerCamera);
173 mOgrePickerCamera->setFarClipDistance(100.0f);
174 mOgrePickerCamera->setNearClipDistance(0.1f);
176 Ogre::Viewport* pickerViewport = mOgrePickerRenderTexture->addViewport(mOgrePickerCamera);
177 pickerViewport->setOverlaysEnabled(
false);
178 pickerViewport->setShadowsEnabled(
false);
182 mOgrePickerRect =
new Ogre::Rectangle2D(
true);
183 mOgrePickerRect->setCastShadows(
false);
187 mOgrePickerRect->setMaterial(mPickerMat);
189 catch (Ogre::Exception &e)
191 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage(
"An exception has occurred: " + e.getDescription());
194 mOgrePickerRect->setRenderQueueGroup(Ogre::RENDER_QUEUE_BACKGROUND);
195 mOgrePickerScene->getRootSceneNode()->attachObject(mOgrePickerRect);
196 mOgrePickerRect->setCorners(-1.0f, 1.0f, 1.0f, -1.0f);
199 Ogre::AxisAlignedBox aabInf;
200 aabInf.setInfinite();
201 mOgrePickerRect->setBoundingBox(aabInf);
202 mOgrePickerRect->setVisible(
true);
208 if (mOgrePickerRect != 0)
210 mOgrePickerRect->detachFromParent();
211 SAFE_DELETE(mOgrePickerRect);
214 if (mOgrePickerScene)
216 mOgrePickerScene->destroyAllCameras();
217 Ogre::Root::getSingleton().destroySceneManager(mOgrePickerScene);
218 mOgrePickerCamera = 0;
219 mOgrePickerScene = 0;
222 if (mOgrePickerRenderTexture)
224 mOgrePickerRenderTexture->removeAllViewports();
225 mOgrePickerRenderTexture = 0;
228 if (mOgrePickerTexture)
230 Ogre::TextureManager::getSingleton().remove(mOgrePickerTexture->getHandle());
231 mOgrePickerTexture.reset();
234 SO3_SAFE_DELETE(mOgrePixelBox);
235 SO3_SAFE_DELETE_ARRAY(mRenderPickerBuffer);
240 return mUseDepth && mOgreRenderDepthTexture;
250 posX = (int)(((
float)mTextureWidth / (
float)mRealWidth) * (float)posX);
251 posY = (int)(((
float)mTextureHeight / (float)mRealHeight) * (float)posY);
254 if (mOgrePickerRenderTexture && (posX >= 0) && (posY >= 0))
257 Ogre::Technique* pickerTech = 0;
258 Ogre::Material::Techniques techs = mPickerMat->getTechniques();
260 if (techs.size() == 0)
263 pickerTech = techs[0];
265 Ogre::Vector4 mousePos;
266 mousePos.x = (1.0f / (float)mTextureWidth) * (float)posX;
267 mousePos.y = (1.0f / (float)mTextureHeight) * (float)posY;
270 Ogre::ColourValue ogreColour;
274 Ogre::Pass* pickerPass = pickerTech->getPass(0);
275 Ogre::GpuProgramParametersSharedPtr fparams = pickerPass->getFragmentProgramParameters();
276 fparams->setNamedConstant(
"inMouse", mousePos);
278 pickerPass->getTextureUnitState(0)->setTexture(mOgreTexture);
294 mOgrePickerRenderTexture->update();
295 mOgrePickerRenderTexture->copyContentsToMemory(Ogre::Box(0, 0, 1, 1), *mOgrePixelBox, Ogre::RenderTarget::FB_AUTO);
297 if (mRenderPickerBuffer)
298 ogreColour = mOgrePixelBox->getColourAt(0, 0, 0);
302 catch (Ogre::Exception&)
309 Ogre::SubEntity* selectedEntity = nodeSelectorMaterialSwitcher->
GetSubEntity(ogreColour);
310 return selectedEntity;
322 posX = (int)(((
float)mTextureWidth / (
float)mRealWidth) * (float)posX);
323 posY = (int)(((
float)mTextureHeight / (float)mRealHeight) * (float)posY);
326 if (mOgreDepthTexture && (posX >= 0) && (posY >= 0))
329 Ogre::Technique* pickerTech = 0;
330 Ogre::Material::Techniques techs = mPickerMat->getTechniques();
332 if (techs.size() == 0)
335 pickerTech = techs[0];
337 Ogre::Vector4 mousePos;
338 mousePos.x = (1.0f / (float)mTextureWidth) * (float)posX;
339 mousePos.y = (1.0f / (float)mTextureHeight) * (float)posY;
343 Ogre::ColourValue ogreColour;
346 Ogre::Pass* pickerPass = pickerTech->getPass(0);
347 Ogre::GpuProgramParametersSharedPtr fparams = pickerPass->getFragmentProgramParameters();
348 fparams->setNamedConstant(
"inMouse", mousePos);
350 pickerPass->getTextureUnitState(0)->setTexture(mOgreDepthTexture);
366 mOgrePickerRenderTexture->update();
367 mOgrePickerRenderTexture->copyContentsToMemory(Ogre::Box(0, 0, 1, 1), *mOgrePixelBox, Ogre::RenderTarget::FB_AUTO);
369 if (mRenderPickerBuffer)
370 ogreColour = mOgrePixelBox->getColourAt(0, 0, 0);
373 Ogre::Vector4 shift(1.0f / (256.0f * 256.0f * 256.0f), 1.0f / (256.0f * 256.0f), 1.0f / 256.0f, 1.0f);
374 zpos = Ogre::Vector4(ogreColour.a, ogreColour.b, ogreColour.g, ogreColour.r).dotProduct(shift);
376 catch (Ogre::Exception&)
387void SSubEntityCameraSelectorBuffer::CreateTexture(
const unsigned int& width,
const unsigned int& height)
391 const Ogre::RenderSystemCapabilities* caps = ogreRenderSystem->getCapabilities();
394 if (caps && (!caps->hasCapability(Ogre::RSC_NON_POWER_OF_2_TEXTURES)
396 || caps->getNonPOW2TexturesLimited()
400 mTextureWidth = Ogre::Bitwise::firstPO2From(width / 3) / 2;
401 mTextureHeight = Ogre::Bitwise::firstPO2From(height / 3) / 2;
403 mTextureWidth = std::max(mTextureWidth, mTextureHeight);
404 mTextureHeight = mTextureWidth;
408 mTextureWidth = width;
409 mTextureHeight = height;
412 mCompensateNPOT =
true;
415 mRealHeight = height;
418 std::string textureName = mBaseResourceName +
"/Texture";
421 Ogre::PixelFormat rttpf = Ogre::PF_A8R8G8B8;
423 mOgreTexture = Ogre::TextureManager::getSingleton().createManual(textureName, SO3_INTERNAL_SUBENTITY_SELECTOR_RESOURCE_GROUP, Ogre::TEX_TYPE_2D, mTextureWidth, mTextureHeight, 0, rttpf, Ogre::TU_RENDERTARGET);
424 mOgreTexture->load();
429 mOgreDepthTexture = Ogre::TextureManager::getSingleton().createManual(textureName +
"/Depth", SO3_INTERNAL_SUBENTITY_SELECTOR_RESOURCE_GROUP, Ogre::TEX_TYPE_2D, mTextureWidth, mTextureHeight, 0, rttpf, Ogre::TU_RENDERTARGET);
430 mOgreDepthTexture->load();
433 catch (Ogre::Exception &e)
435 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage(
"An exception has occurred in SSubEntityCameraSelectorBuffer::CreateTexture : " + e.getDescription());
436 mOgreTexture.reset();
437 mOgreDepthTexture.reset();
443 Ogre::HardwarePixelBufferSharedPtr ogrePixelBuffer = mOgreTexture->getBuffer();
444 mOgreRenderTexture = ogrePixelBuffer->getRenderTarget();
445 mOgreRenderTexture->setAutoUpdated(
true);
446 mOgreRenderTexture->setPriority(100);
448#if defined(APPLE_IOS)
449 mOgreRenderTexture->setDepthBufferPool(Ogre::DepthBuffer::POOL_NO_DEPTH);
452 if (mOgreDepthTexture)
454 Ogre::HardwarePixelBufferSharedPtr ogreDepthPixelBuffer = mOgreDepthTexture->getBuffer();
455 mOgreRenderDepthTexture = ogreDepthPixelBuffer->getRenderTarget();
456 mOgreRenderDepthTexture->setAutoUpdated(
false);
457 mOgreRenderDepthTexture->setPriority(100);
460 mOgreRenderTexture->setAutoUpdated(
false);
462#if defined(APPLE_IOS)
463 mOgreRenderDepthTexture->setDepthBufferPool(Ogre::DepthBuffer::POOL_NO_DEPTH);
465 mMrtTexture = Ogre::Root::getSingleton().getRenderSystem()->createMultiRenderTarget(textureName +
"/MRT");
468 mMrtTexture->bindSurface(0, mOgreRenderTexture);
469 mMrtTexture->bindSurface(1, mOgreRenderDepthTexture);
470 mMrtTexture->setAutoUpdated(
true);
474 Ogre::Viewport* ogreRenderWindowViewport = mCamera->getViewport();
475 Ogre::Real ratio = mCamera->getAspectRatio();
477 Ogre::Viewport* ogreRenderTextureViewport = mOgreRenderTexture->addViewport(mCamera);
479 ogreRenderTextureViewport->setClearEveryFrame(
true);
480 ogreRenderTextureViewport->setOverlaysEnabled(
false);
481 ogreRenderTextureViewport->setMaterialScheme(mBaseResourceName);
482 ogreRenderTextureViewport->setShadowsEnabled(
false);
483 ogreRenderTextureViewport->setSkiesEnabled(
false);
484 ogreRenderTextureViewport->setVisibilityMask(ogreRenderTextureViewport->getVisibilityMask() & ~SO3_VISIBILITY_FLAG_INVISIBLE_ENVIRONMENT &~Ogre::SceneManager::FX_TYPE_MASK &~Ogre::SceneManager::LIGHT_TYPE_MASK);
486 Ogre::Viewport* ogreRenderDepthTextureViewport = 0;
487 if (mOgreRenderDepthTexture)
489 ogreRenderDepthTextureViewport = mOgreRenderDepthTexture->addViewport(mCamera);
490 ogreRenderDepthTextureViewport->setClearEveryFrame(
true);
491 ogreRenderDepthTextureViewport->setOverlaysEnabled(
false);
492 ogreRenderDepthTextureViewport->setMaterialScheme(mBaseResourceName);
493 ogreRenderDepthTextureViewport->setShadowsEnabled(
false);
494 ogreRenderDepthTextureViewport->setSkiesEnabled(
false);
495 ogreRenderDepthTextureViewport->setVisibilityMask(ogreRenderDepthTextureViewport->getVisibilityMask() & ~SO3_VISIBILITY_FLAG_INVISIBLE_ENVIRONMENT &~Ogre::SceneManager::FX_TYPE_MASK &~Ogre::SceneManager::LIGHT_TYPE_MASK);
498 Ogre::Viewport* ogreRenderMrtViewport = 0;
501 ogreRenderMrtViewport = mMrtTexture->addViewport(mCamera);
502 ogreRenderMrtViewport->setClearEveryFrame(
true);
503 ogreRenderMrtViewport->setOverlaysEnabled(
false);
504 ogreRenderMrtViewport->setMaterialScheme(mBaseResourceName);
505 ogreRenderMrtViewport->setShadowsEnabled(
false);
506 ogreRenderMrtViewport->setSkiesEnabled(
false);
507 ogreRenderMrtViewport->setVisibilityMask(ogreRenderMrtViewport->getVisibilityMask() & ~SO3_VISIBILITY_FLAG_INVISIBLE_ENVIRONMENT &~Ogre::SceneManager::FX_TYPE_MASK &~Ogre::SceneManager::LIGHT_TYPE_MASK);
510 if (ogreRenderWindowViewport)
513 mCamera->setAspectRatio(ratio);
516 mCamera->_notifyViewport(ogreRenderWindowViewport);
521 mOgreRenderTexture->addListener(
this);
523 mMrtTexture->addListener(
this);
527void SSubEntityCameraSelectorBuffer::DeleteTexture()
529 if (mOgreRenderTexture)
532 mOgreRenderTexture->removeListener(
this);
533 mOgreRenderTexture->removeAllViewports();
535 mOgreRenderTexture = 0;
538 if (mOgreRenderDepthTexture)
540 mOgreRenderDepthTexture->removeAllViewports();
541 mOgreRenderDepthTexture = 0;
546 mMrtTexture->removeListener(
this);
547 mMrtTexture->removeAllViewports();
548 Ogre::Root::getSingleton().getRenderSystem()->destroyRenderTarget(mBaseResourceName +
"/Texture/MRT");
554 Ogre::TextureManager::getSingleton().remove(mOgreTexture->getHandle());
555 mOgreTexture.reset();
558 if (mOgreDepthTexture)
560 Ogre::TextureManager::getSingleton().remove(mOgreDepthTexture->getHandle());
561 mOgreDepthTexture.reset();
572 if ((texwidth != mRealWidth)
573 || (texheight != mRealHeight)
575 || (!mOgreRenderTexture))
580 CreateTexture(texwidth, texheight);
582 catch (Ogre::Exception &)
591 if (evt.source == mOgreRenderTexture || evt.source == mMrtTexture)
595 Ogre::MaterialManager::getSingleton().addListener(nodeSelectorMaterialSwitcher, mBaseResourceName);
601 if (((evt.source == mOgreRenderTexture) && mOgreRenderTexture->isActive()) || ((evt.source == mMrtTexture) && mMrtTexture->isActive()))
604 Ogre::MaterialManager::getSingleton().removeListener(nodeSelectorMaterialSwitcher, mBaseResourceName);
bool GetRttPixelFormat(Ogre::PixelFormat &format, bool alpha=false, bool floattex=false)
Ogre::RenderSystem * GetOgreRenderSystem()
static SRoot & getSingleton()
static SRoot * getSingletonPtr()
float GetSelectedZdepth(int posX, int posY)
virtual void preRenderTargetUpdate(const Ogre::RenderTargetEvent &evt)
void UpdateBufferSize(unsigned int texwidth, unsigned int texheight, const bool &forceRefresh=false)
~SSubEntityCameraSelectorBuffer()
Ogre::SubEntity * GetSelectedSubEntity(int posX, int posY)
virtual void postRenderTargetUpdate(const Ogre::RenderTargetEvent &evt)
void ResetPriorizedObject()
Ogre::SubEntity * GetSubEntity(const Ogre::ColourValue &searchedColour)