Project

General

Profile

SO3Engine
SO3SubEntitySelectorBuffer.cpp
Go to the documentation of this file.
1/*
2-----------------------------------------------------------------------------
3This source file is part of OpenSpace3D
4For the latest info, see http://www.openspace3d.com
5
6Copyright (c) 2012 I-maginer
7
8This program is free software; you can redistribute it and/or modify it under
9the terms of the GNU Lesser General Public License as published by the Free Software
10Foundation; either version 2 of the License, or (at your option) any later
11version.
12
13This program is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public License along with
18this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20http://www.gnu.org/copyleft/lesser.txt
21
22-----------------------------------------------------------------------------
23*/
24
34#include "SO3Renderer/SO3Root.h"
38#include <OgreBitwise.h>
39#include <OgreDepthBuffer.h>
40
41namespace SO3
42{
43
44SSubEntitySelectorBuffer::SSubEntitySelectorBuffer(SWindow* targetWindow, bool useDepth)
45{
46 mBaseResourceName = std::string(SO3_INTERNAL_SUBENTITY_SELECTOR_RESOURCE_GROUP) +"/"+ targetWindow->GetName();
47
48 Ogre::String rendererName = SRoot::getSingletonPtr()->GetOgreRenderSystem()->getName();
49 if (rendererName == "Vulkan Rendering Subsystem")
50 useDepth = false;
51
52 // Create a custom resource group
53 Ogre::ResourceGroupManager::getSingleton().createResourceGroup(mBaseResourceName, false);
54
55 // Basic initializing
56 mWindow = targetWindow;
57 mRenderPickerBuffer = 0;
58 mOgrePixelBox = 0;
59 mOgreRenderTexture = 0;
60 mOgreRenderDepthTexture = 0;
61 mMrtTexture = 0;
62 mOgreDebugOverlay = 0;
63 mOgreDebugOverlayPanel = 0;
64 mOgreOverlayMaterial.reset();
65 mRealWidth = 0;
66 mRealHeight = 0;
67 mTextureWidth = 0;
68 mTextureHeight = 0;
69 mCompensateNPOT = false;
70 mUseDepth = useDepth;
71 nodeSelectorMaterialSwitcher = 0;
72 mOgreRenderWindow = static_cast <Ogre::RenderTarget*> (const_cast <Ogre::RenderWindow*> (mWindow->GetOgreRenderWindowPointer()));
73
74 mOgrePickerRect = 0;
75 mOgrePickerRenderTexture = 0;
76 mOgrePickerScene = 0;
77 mOgrePickerCamera = 0;
78
79 Ogre::RenderSystem* ogreRenderSystem = SRoot::getSingleton().GetOgreRenderSystem();
80 const Ogre::RenderSystemCapabilities* caps = ogreRenderSystem->getCapabilities();
81 if (mUseDepth && caps && !caps->hasCapability(Ogre::RSC_MRT_SAME_BIT_DEPTHS))
82 mUseDepth = true;
83 else
84 mUseDepth = false;
85
86 //get materials
87 mPickerMat = Ogre::MaterialManager::getSingletonPtr()->getByName("SO3/Internal/EntitySelector/Material/MouseColor");
88 if (mPickerMat)
89 {
90 // Create the render texture.
91 CreateTexture(mOgreRenderWindow->getWidth(), mOgreRenderWindow->getHeight());
93
94 // Create our material switcher.
95 nodeSelectorMaterialSwitcher = new SSubEntitySelectorMaterialSwitcher(mBaseResourceName, UseDepthBuffer());
96 }
97}
98
99SSubEntitySelectorBuffer::SSubEntitySelectorBuffer()
100{
101 // Forbiden (private)
102}
103
105{
106 DeleteTexture();
107 DeletePicker();
108
109 Ogre::ResourceGroupManager::getSingleton().unloadResourceGroup(mBaseResourceName);
110 Ogre::ResourceGroupManager::getSingleton().clearResourceGroup(mBaseResourceName);
111 Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup(mBaseResourceName);
112
113 SO3_SAFE_DELETE(nodeSelectorMaterialSwitcher);
114}
115
117{
118 DeleteTexture();
119 DeletePicker();
120}
121
123{
124 DeleteTexture();
125 DeletePicker();
126
127 CreateTexture(mOgreRenderWindow->getWidth(), mOgreRenderWindow->getHeight());
128 CreatePicker();
129}
130
132{
133 DeletePicker();
134
135 Ogre::PixelFormat rttpf = Ogre::PF_A8R8G8B8;
136 try
137 {
138 SRoot::getSingleton().GetRttPixelFormat(rttpf, mUseDepth ? true : false);
139 mOgrePickerTexture = Ogre::TextureManager::getSingleton().createManual(mBaseResourceName + "/Picker", SO3_INTERNAL_SUBENTITY_SELECTOR_RESOURCE_GROUP, Ogre::TEX_TYPE_2D, 1, 1, 0, rttpf, Ogre::TU_RENDERTARGET);
140 mOgrePickerTexture->load();
141 }
142 catch (Ogre::Exception &e)
143 {
144 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage("An exception has occurred in SSubEntitySelectorBuffer::CreatePicker : "+ e.getDescription());
145 mOgrePickerTexture.reset();
146 }
147
148 if (mOgrePickerTexture)
149 {
150 // Bind to a render texture
151 Ogre::HardwarePixelBufferSharedPtr ogrePixelBuffer = mOgrePickerTexture->getBuffer();
152 mOgrePickerRenderTexture = ogrePixelBuffer->getRenderTarget();
153 mOgrePickerRenderTexture->setAutoUpdated(false);
154
155#if defined(APPLE_IOS)
156 mOgrePickerRenderTexture->setDepthBufferPool(Ogre::DepthBuffer::POOL_NO_DEPTH);
157#endif
158
159 // Create our buffer
160 size_t bufferSize = ogrePixelBuffer->getSizeInBytes();
161 mRenderPickerBuffer = new Ogre::uint8[bufferSize];
162 mOgrePixelBox = new Ogre::PixelBox(ogrePixelBuffer->getWidth(), ogrePixelBuffer->getHeight(), ogrePixelBuffer->getDepth(), ogrePixelBuffer->getFormat(), mRenderPickerBuffer);
163
164 //create scene
165 mOgrePickerScene = Ogre::Root::getSingleton().createSceneManager(Ogre::SMT_DEFAULT, mBaseResourceName+ "/Picker/Scene");
166
167 Ogre::AxisAlignedBox octreeBox(-1, -1, -1, 1, 1, 1);
168 int octreeDepth = 0;
169 mOgrePickerScene->setOption("Size", &octreeBox);
170 mOgrePickerScene->setOption("Depth", &octreeDepth);
171
172 Ogre::RenderQueue* rq = mOgrePickerScene->getRenderQueue();
173 rq->getQueueGroup(Ogre::RENDER_QUEUE_WORLD_GEOMETRY_1)->setShadowsEnabled(false);
174 rq->getQueueGroup(Ogre::RENDER_QUEUE_WORLD_GEOMETRY_2)->setShadowsEnabled(false);
175 rq->getQueueGroup(Ogre::RENDER_QUEUE_MAIN)->setShadowsEnabled(false);
176 rq->getQueueGroup(49)->setShadowsEnabled(false);
177
178 //set camera
179 mOgrePickerCamera = mOgrePickerScene->createCamera(mBaseResourceName+ "/Picker/Camera");
180 mOgrePickerScene->getRootSceneNode()->attachObject(mOgrePickerCamera);
181 mOgrePickerCamera->setFarClipDistance(100.0f);
182 mOgrePickerCamera->setNearClipDistance(0.1f);
183
184 Ogre::Viewport* pickerViewport = mOgrePickerRenderTexture->addViewport(mOgrePickerCamera);
185 pickerViewport->setOverlaysEnabled(false);
186 pickerViewport->setShadowsEnabled(false);
187 //mOgrePickerViewport->setSkiesEnabled(false);
188
189 //create rect
190 mOgrePickerRect = new Ogre::Rectangle2D(true);
191 mOgrePickerRect->setCastShadows(false);
192
193 try
194 {
195 mOgrePickerRect->setMaterial(mPickerMat);
196 }
197 catch(Ogre::Exception &e)
198 {
199 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage("An exception has occurred: " + e.getDescription());
200 }
201
202 mOgrePickerRect->setRenderQueueGroup(Ogre::RENDER_QUEUE_BACKGROUND);
203 mOgrePickerScene->getRootSceneNode()->attachObject(mOgrePickerRect);
204 mOgrePickerRect->setCorners(-1.0f, 1.0f, 1.0f, -1.0f);
205
206 // Use infinite AAB to always stay visible
207 Ogre::AxisAlignedBox aabInf;
208 aabInf.setInfinite();
209 mOgrePickerRect->setBoundingBox(aabInf);
210 mOgrePickerRect->setVisible(true);
211
212 // Show debug overlay.
213#if SO3_SUBENTITY_SELECTOR_DEBUG_OVERLAY
214 //CreateDebugOverlay();
215#endif
216 }
217}
218
220{
221 // hide debug overlay.
222#if SO3_SUBENTITY_SELECTOR_DEBUG_OVERLAY
223 //DeleteDebugOverlay();
224#endif
225
226 if(mOgrePickerRect != 0)
227 {
228 mOgrePickerRect->detachFromParent();
229 SAFE_DELETE(mOgrePickerRect);
230 }
231
232 if (mOgrePickerScene)
233 {
234 mOgrePickerScene->destroyAllCameras();
235 Ogre::Root::getSingleton().destroySceneManager(mOgrePickerScene);
236 mOgrePickerCamera = 0;
237 mOgrePickerScene = 0;
238 }
239
240 if(mOgrePickerRenderTexture)
241 {
242 mOgrePickerRenderTexture->removeAllViewports();
243 mOgrePickerRenderTexture = 0;
244 }
245
246 if (mOgrePickerTexture)
247 {
248 Ogre::TextureManager::getSingleton().remove(mOgrePickerTexture->getHandle());
249 mOgrePickerTexture.reset();
250 }
251
252 SO3_SAFE_DELETE(mOgrePixelBox);
253 SO3_SAFE_DELETE_ARRAY(mRenderPickerBuffer);
254}
255
257{
258 Ogre::Viewport* renderWindowViewport = mOgreRenderWindow->getViewport(newViewport->GetPriority());
259
260 mSelectorViewportList[newViewport] = 0;
261}
262
264{
265 SelectorViewportList::iterator iSearchedOgreViewport = mSelectorViewportList.find(existingViewport);
266 if(iSearchedOgreViewport != mSelectorViewportList.end())
267 {
268 mSelectorViewportList.erase(iSearchedOgreViewport);
269 }
270}
271
273{
274 return mUseDepth && mOgreRenderDepthTexture;
275}
276
277Ogre::SubEntity* SSubEntitySelectorBuffer::GetSelectedSubEntity(int posX, int posY)
278{
279 if (!mPickerMat)
280 return 0;
281
282 if (mCompensateNPOT)
283 {
284 posX = (int)(((float)mTextureWidth / (float)mRealWidth) * (float)posX);
285 posY = (int)(((float)mTextureHeight / (float)mRealHeight) * (float)posY);
286 }
287
288 if (mOgrePickerRenderTexture && (posX >= 0) && (posY >= 0))
289 {
290 //set material parameters
291 Ogre::Technique* pickerTech = 0;
292 Ogre::Material::Techniques techs = mPickerMat->getTechniques();
293
294 if (techs.size() == 0)
295 return 0;
296
297 pickerTech = techs[0];
298
299 Ogre::Vector4 mousePos;
300 mousePos.x = (1.0f / (float)mTextureWidth) * (float)posX;
301 mousePos.y = (1.0f / (float)mTextureHeight) * (float)posY;
302
303 Ogre::ARGB argb(0);
304 Ogre::ColourValue ogreColour;
305
306 try
307 {
308 Ogre::Pass* pickerPass = pickerTech->getPass(0);
309 Ogre::GpuProgramParametersSharedPtr fparams = pickerPass->getFragmentProgramParameters();
310 fparams->setNamedConstant("inMouse", mousePos);
311
312 pickerPass->getTextureUnitState(0)->setTexture(mOgreTexture);
313
314 // debug
315 /*
316 Ogre::PixelBox pb(mOgreRenderTexture->getWidth(), mOgreRenderTexture->getHeight(), 1, mOgreRenderTexture->suggestPixelFormat());
317 pb.data = new uint8[pb.getConsecutiveSize()];
318 mOgreRenderTexture->copyContentsToMemory(pb, pb);
319
320 Ogre::Image finalImage;
321 finalImage.loadDynamicImage(static_cast<unsigned char*>(pb.data), pb.getWidth(), pb.getHeight(), mOgreRenderTexture->suggestPixelFormat());
322
323 //write the file on the Harddisk
324 finalImage.save("E:\\Documents\\OpenSpace3D\\dselector_debug.png");
325 delete[] pb.data;
326 */
327
328 mOgrePickerRenderTexture->update();
329 mOgrePickerRenderTexture->copyContentsToMemory(Ogre::Box(0, 0, 1, 1), *mOgrePixelBox, Ogre::RenderTarget::FB_AUTO);
330
331 if (mRenderPickerBuffer)
332 ogreColour = mOgrePixelBox->getColourAt(0, 0, 0);
333
334 ogreColour.a = 1.0f;
335 }
336 catch(Ogre::Exception&)
337 {
338 //Renderer not ready
339 return 0;
340 }
341
342 // Get sub entity
343 Ogre::SubEntity* selectedEntity = (nodeSelectorMaterialSwitcher) ? nodeSelectorMaterialSwitcher->GetSubEntity(ogreColour) : 0;
344 return selectedEntity;
345 }
346 return 0;
347}
348
350{
351 if (!mPickerMat)
352 return 0;
353
354 if (mCompensateNPOT)
355 {
356 posX = (int)(((float)mTextureWidth / (float)mRealWidth) * (float)posX);
357 posY = (int)(((float)mTextureHeight / (float)mRealHeight) * (float)posY);
358 }
359
360 if (mOgreDepthTexture && (posX >= 0) && (posY >= 0))
361 {
362 //set material parameters
363 Ogre::Technique* pickerTech = 0;
364 Ogre::Material::Techniques techs = mPickerMat->getTechniques();
365
366 if (techs.size() == 0)
367 return 0;
368
369 pickerTech = techs[0];
370
371 Ogre::Vector4 mousePos;
372 mousePos.x = (1.0f / (float)mTextureWidth) * (float)posX;
373 mousePos.y = (1.0f / (float)mTextureHeight) * (float)posY;
374
375 float zpos = 0.0f;
376 Ogre::ARGB argb(0);
377 Ogre::ColourValue ogreColour;
378 try
379 {
380 Ogre::Pass* pickerPass = pickerTech->getPass(0);
381 Ogre::GpuProgramParametersSharedPtr fparams = pickerPass->getFragmentProgramParameters();
382 fparams->setNamedConstant("inMouse", mousePos);
383
384 pickerPass->getTextureUnitState(0)->setTexture(mOgreDepthTexture);
385
386 // debug
387 /*
388 Ogre::PixelBox pb(mOgreRenderDepthTexture->getWidth(), mOgreRenderDepthTexture->getHeight(), 1, mOgreRenderDepthTexture->suggestPixelFormat());
389 pb.data = new uint8[pb.getConsecutiveSize()];
390 mOgreRenderDepthTexture->copyContentsToMemory(pb, pb);
391
392 Ogre::Image finalImage;
393 finalImage.loadDynamicImage(static_cast<unsigned char*>(pb.data), pb.getWidth(), pb.getHeight(), mOgreRenderDepthTexture->suggestPixelFormat());
394
395 //write the file on the Harddisk
396 finalImage.save("D:\\Documents\\OpenSpace3D\\depth_debug.png");
397 delete[] pb.data;
398 */
399
400 mOgrePickerRenderTexture->update();
401 mOgrePickerRenderTexture->copyContentsToMemory(Ogre::Box(0, 0, 1, 1), *mOgrePixelBox, Ogre::RenderTarget::FB_AUTO);
402
403 if (mRenderPickerBuffer)
404 ogreColour = mOgrePixelBox->getColourAt(0, 0, 0);
405
406 //unpack RGBA to float
407 Ogre::Vector4 shift(1.0f / (256.0f * 256.0f * 256.0f), 1.0f / (256.0f * 256.0f), 1.0f / 256.0f, 1.0f);
408 zpos = Ogre::Vector4(ogreColour.a, ogreColour.b, ogreColour.g, ogreColour.r).dotProduct(shift);
409 }
410 catch (Ogre::Exception&)
411 {
412 //Renderer not ready
413 return 0.0f;
414 }
415
416 return zpos;
417 }
418 return 0.0f;
419}
420
421void SSubEntitySelectorBuffer::CreateTexture(const unsigned int& width, const unsigned int& height)
422{
423 // Check if size need pow2
424 Ogre::RenderSystem* ogreRenderSystem = SRoot::getSingleton().GetOgreRenderSystem();
425 const Ogre::RenderSystemCapabilities* caps = ogreRenderSystem->getCapabilities();
426
427 //optim test divide the texture size to get a faster frame rate on copyContentsToMemory
428 if (caps && (!caps->hasCapability(Ogre::RSC_NON_POWER_OF_2_TEXTURES)
429#ifdef APPLE_IOS
430 || caps->getNonPOW2TexturesLimited()
431#endif
432 ))
433 {
434 mTextureWidth = Ogre::Bitwise::firstPO2From(width / 3) / 2;
435 mTextureHeight = Ogre::Bitwise::firstPO2From(height / 3) / 2;
436
437 mTextureWidth = std::max(mTextureWidth, mTextureHeight);
438 mTextureHeight = mTextureWidth;
439 }
440 else
441 {
442#ifdef _WIN32
443 mTextureWidth = width; // / 2;
444 mTextureHeight = height; // / 2;
445#else
446 mTextureWidth = (width / 4);
447 mTextureHeight = (height / 4);
448#endif
449 }
450
451 mCompensateNPOT = true;
452
453 mRealWidth = width;
454 mRealHeight = height;
455
456 // Generate a texture with an unique name.
457 std::string textureName = mBaseResourceName+ "/Texture";
458 try
459 {
460 Ogre::PixelFormat rttpf = Ogre::PF_A8R8G8B8;
461 SRoot::getSingleton().GetRttPixelFormat(rttpf, mUseDepth ? true : false);
462 mOgreTexture = Ogre::TextureManager::getSingleton().createManual(textureName, SO3_INTERNAL_SUBENTITY_SELECTOR_RESOURCE_GROUP, Ogre::TEX_TYPE_2D, mTextureWidth, mTextureHeight, 0, rttpf, Ogre::TU_RENDERTARGET);
463 mOgreTexture->load();
464
465 if (mUseDepth)
466 {
468 mOgreDepthTexture = Ogre::TextureManager::getSingleton().createManual(textureName + "/Depth", SO3_INTERNAL_SUBENTITY_SELECTOR_RESOURCE_GROUP, Ogre::TEX_TYPE_2D, mTextureWidth, mTextureHeight, 0, rttpf, Ogre::TU_RENDERTARGET);
469 mOgreDepthTexture->load();
470 }
471 }
472 catch (Ogre::Exception &e)
473 {
474 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage("An exception has occurred in SSubEntitySelectorBuffer::CreateTexture : "+ e.getDescription());
475 mOgreTexture.reset();
476 mOgreDepthTexture.reset();
477 }
478
479 if (mOgreTexture)
480 {
481 // Bind to a render texture
482 Ogre::HardwarePixelBufferSharedPtr ogrePixelBuffer = mOgreTexture->getBuffer();
483 mOgreRenderTexture = ogrePixelBuffer->getRenderTarget();
484 mOgreRenderTexture->setAutoUpdated(true);
485 mOgreRenderTexture->setPriority(100);
486
487#if defined(APPLE_IOS)
488 mOgreRenderTexture->setDepthBufferPool(Ogre::DepthBuffer::POOL_NO_DEPTH);
489#endif
490
491 if (mOgreDepthTexture)
492 {
493 Ogre::HardwarePixelBufferSharedPtr ogreDepthPixelBuffer = mOgreDepthTexture->getBuffer();
494 mOgreRenderDepthTexture = ogreDepthPixelBuffer->getRenderTarget();
495 mOgreRenderDepthTexture->setAutoUpdated(false);
496 mOgreRenderDepthTexture->setPriority(100);
497
498 //also disable auto render on entity texture for mrt
499 mOgreRenderTexture->setAutoUpdated(false);
500
501#if defined(APPLE_IOS)
502 mOgreRenderDepthTexture->setDepthBufferPool(Ogre::DepthBuffer::POOL_NO_DEPTH);
503#endif
504 mMrtTexture = Ogre::Root::getSingleton().getRenderSystem()->createMultiRenderTarget(textureName + "/MRT");
505 if (mMrtTexture)
506 {
507 mMrtTexture->bindSurface(0, mOgreRenderTexture);
508 mMrtTexture->bindSurface(1, mOgreRenderDepthTexture);
509 mMrtTexture->setAutoUpdated(true);
510 }
511 }
512
513 // Handle camera switching and multiples viewports on a mWindow.
514 const SelectorViewportList viewportListCopy = mSelectorViewportList;
515 SelectorViewportList::const_iterator iOgreViewportList = viewportListCopy.begin();
516 while(iOgreViewportList != viewportListCopy.end())
517 {
518 // Get windows viewport infos.
519 SViewPort* renderWindowViewport = iOgreViewportList->first;
520 SCamera* renderWindowCamera = renderWindowViewport->GetCamera();
521 if (renderWindowCamera)
522 {
523 Ogre::Camera* ogreRenderWindowCamera = renderWindowCamera->GetOgreCameraPointer();
524 Ogre::Real ratio = ogreRenderWindowCamera->getAspectRatio();
525 Ogre::Viewport* ogreRenderWindowViewport = renderWindowViewport->GetOgreViewPortPointer();
526 Ogre::Viewport* ogreRenderTextureViewport = mOgreRenderTexture->addViewport(ogreRenderWindowCamera, ogreRenderWindowViewport->getZOrder(), ogreRenderWindowViewport->getLeft(), ogreRenderWindowViewport->getTop(), ogreRenderWindowViewport->getWidth(), ogreRenderWindowViewport->getHeight());
527
528 ogreRenderTextureViewport->setClearEveryFrame(true);
529 ogreRenderTextureViewport->setOverlaysEnabled(false);
530 ogreRenderTextureViewport->setMaterialScheme(mBaseResourceName);
531 ogreRenderTextureViewport->setShadowsEnabled(false);
532 ogreRenderTextureViewport->setSkiesEnabled(false);
533 ogreRenderTextureViewport->setVisibilityMask(ogreRenderWindowViewport->getVisibilityMask() & ~SO3_VISIBILITY_FLAG_INVISIBLE_ENVIRONMENT &~Ogre::SceneManager::FX_TYPE_MASK &~Ogre::SceneManager::LIGHT_TYPE_MASK); // Hide environment object in this rtt (skyx & hydrax).
534
535 Ogre::Viewport* ogreRenderDepthTextureViewport = 0;
536 if (mOgreRenderDepthTexture)
537 {
538 ogreRenderDepthTextureViewport = mOgreRenderDepthTexture->addViewport(ogreRenderWindowCamera, ogreRenderWindowViewport->getZOrder(), ogreRenderWindowViewport->getLeft(), ogreRenderWindowViewport->getTop(), ogreRenderWindowViewport->getWidth(), ogreRenderWindowViewport->getHeight());
539 ogreRenderDepthTextureViewport->setClearEveryFrame(true);
540 ogreRenderDepthTextureViewport->setOverlaysEnabled(false);
541 ogreRenderDepthTextureViewport->setMaterialScheme(mBaseResourceName);
542 ogreRenderDepthTextureViewport->setShadowsEnabled(false);
543 ogreRenderDepthTextureViewport->setSkiesEnabled(false);
544 ogreRenderDepthTextureViewport->setVisibilityMask(ogreRenderWindowViewport->getVisibilityMask() & ~SO3_VISIBILITY_FLAG_INVISIBLE_ENVIRONMENT &~Ogre::SceneManager::FX_TYPE_MASK &~Ogre::SceneManager::LIGHT_TYPE_MASK); // Hide environment object in this rtt (skyx & hydrax).
545 }
546
547 Ogre::Viewport* ogreRenderMrtViewport = 0;
548 if (mMrtTexture)
549 {
550 ogreRenderMrtViewport = mMrtTexture->addViewport(ogreRenderWindowCamera, ogreRenderWindowViewport->getZOrder(), ogreRenderWindowViewport->getLeft(), ogreRenderWindowViewport->getTop(), ogreRenderWindowViewport->getWidth(), ogreRenderWindowViewport->getHeight());
551 ogreRenderMrtViewport->setClearEveryFrame(true);
552 ogreRenderMrtViewport->setOverlaysEnabled(false);
553 ogreRenderMrtViewport->setMaterialScheme(mBaseResourceName);
554 ogreRenderMrtViewport->setShadowsEnabled(false);
555 ogreRenderMrtViewport->setSkiesEnabled(false);
556 ogreRenderMrtViewport->setVisibilityMask(ogreRenderWindowViewport->getVisibilityMask() & ~SO3_VISIBILITY_FLAG_INVISIBLE_ENVIRONMENT &~Ogre::SceneManager::FX_TYPE_MASK &~Ogre::SceneManager::LIGHT_TYPE_MASK); // Hide environment object in this rtt (skyx & hydrax).
557 }
558
559 // Restore aspect ratio
560 ogreRenderWindowCamera->setAspectRatio(ratio);
561
562 // Restore viewport
563 ogreRenderWindowCamera->_notifyViewport(ogreRenderWindowViewport);
564
565 // Update viewport clearing settings.
566 if(renderWindowViewport->GetClearColor() || renderWindowViewport->GetClearDepth())
567 {
568 int mode = 0;
569 if(renderWindowViewport->GetClearDepth() && renderWindowViewport->GetClearColor())
570 mode = Ogre::FBT_COLOUR|Ogre::FBT_DEPTH;
571 else if (renderWindowViewport->GetClearDepth())
572 mode = Ogre::FBT_DEPTH;
573 else
574 mode = Ogre::FBT_COLOUR;
575 ogreRenderTextureViewport->setClearEveryFrame(true, mode);
576
577 if (ogreRenderDepthTextureViewport)
578 ogreRenderDepthTextureViewport->setClearEveryFrame(true, mode);
579
580 if (ogreRenderMrtViewport)
581 ogreRenderMrtViewport->setClearEveryFrame(true, mode);
582 }
583 mSelectorViewportList[renderWindowViewport] = ogreRenderTextureViewport;
584 }
585
586 iOgreViewportList++;
587 }
588
589 // Add a frame listener to detect each new frame (one selection buffer render per frame max).
590 if (!mMrtTexture)
591 mOgreRenderTexture->addListener(this);
592 else
593 mMrtTexture->addListener(this);
594
595#if SO3_SUBENTITY_SELECTOR_DEBUG_OVERLAY
596 CreateDebugOverlay();
597#endif
598 }
599}
600
601void SSubEntitySelectorBuffer::DeleteTexture()
602{
603 if(mOgreRenderTexture)
604 {
605#if SO3_SUBENTITY_SELECTOR_DEBUG_OVERLAY
606 DeleteDebugOverlay();
607#endif
608
609 if (!mMrtTexture)
610 mOgreRenderTexture->removeListener(this);
611 mOgreRenderTexture->removeAllViewports();
612
613 mOgreRenderTexture = 0;
614 }
615
616 if (mOgreRenderDepthTexture)
617 {
618 mOgreRenderDepthTexture->removeAllViewports();
619 mOgreRenderDepthTexture = 0;
620 }
621
622
623 if (mMrtTexture)
624 {
625 mMrtTexture->removeListener(this);
626 mMrtTexture->removeAllViewports();
627 Ogre::Root::getSingleton().getRenderSystem()->destroyRenderTarget(mBaseResourceName + "/Texture/MRT");
628 mMrtTexture = 0;
629 }
630
631 if (mOgreTexture)
632 {
633 Ogre::TextureManager::getSingleton().remove(mOgreTexture->getHandle());
634 mOgreTexture.reset();
635 }
636
637 if (mOgreDepthTexture)
638 {
639 Ogre::TextureManager::getSingleton().remove(mOgreDepthTexture->getHandle());
640 mOgreDepthTexture.reset();
641 }
642}
643
644void SSubEntitySelectorBuffer::CreateDebugOverlay()
645{
646 if (!mOgreDebugOverlay)
647 {
648 std::string ogreOverlayMaterialName = mBaseResourceName+ "/Material/DebugOverlay";
649 mOgreOverlayMaterial = Ogre::MaterialManager::getSingleton().create(ogreOverlayMaterialName, mBaseResourceName);
650 mOgreOverlayMaterial->getTechnique(0)->getPass(0)->createTextureUnitState()->setTexture(mOgreTexture); //mOgrePickerTexture
651 mOgreOverlayMaterial->getTechnique(0)->setLightingEnabled(false);
652
653 Ogre::OverlayManager* overlayManager = Ogre::OverlayManager::getSingletonPtr();
654 mOgreDebugOverlay = overlayManager->create(mBaseResourceName+ "/Overlay/DebugOverlay");
655 mOgreDebugOverlayPanel = static_cast<Ogre::OverlayContainer*> (overlayManager->createOverlayElement("Panel", mBaseResourceName+ "/Overlay/DebugOverlayPanel"));
656 mOgreDebugOverlayPanel->setPosition(0.5f, 0.5f);
657 mOgreDebugOverlayPanel->setDimensions(0.5f, 0.5f);
658 mOgreDebugOverlayPanel->setMaterialName(ogreOverlayMaterialName);
659 mOgreDebugOverlay->add2D(mOgreDebugOverlayPanel);
660 mOgreDebugOverlay->show();
661 }
662}
663
664void SSubEntitySelectorBuffer::DeleteDebugOverlay()
665{
666 if (mOgreDebugOverlay)
667 {
668 // Delete overlay elements.
669 Ogre::OverlayManager* overlayManager = Ogre::OverlayManager::getSingletonPtr();
670 mOgreDebugOverlay->remove2D(mOgreDebugOverlayPanel);
671 overlayManager->destroyOverlayElement(mOgreDebugOverlayPanel);
672 mOgreDebugOverlayPanel = 0;
673 overlayManager->destroy(mOgreDebugOverlay);
674 mOgreDebugOverlay = 0;
675
676 // Delete material.
677 //const Ogre::RenderSystemCapabilities* caps = SRoot::getSingletonPtr()->GetOgreRenderSystem()->getCapabilities();
678 //if (caps && caps->hasCapability(Ogre::RSC_FIXED_FUNCTION) == false)
679 Ogre::RTShader::ShaderGenerator::getSingletonPtr()->removeAllShaderBasedTechniques(mOgreOverlayMaterial->getName(), mOgreOverlayMaterial->getGroup());
680
681 Ogre::MaterialManager::getSingleton().remove(mOgreOverlayMaterial->getHandle());
682 mOgreOverlayMaterial.reset();
683 }
684}
685
687{
688 /*unsigned int newWidth = mOgreRenderWindow->getWidth();
689 unsigned int newHeight = mOgreRenderWindow->getHeight();
690 // Update only once per frame (in case we call GetSelectedEntity multiple times in the same frame).
691 // Or if the buffer size changed
692 if(needUpdate || forceUpdate || ((newWidth != mRealWidth)||(newHeight != mRealHeight)) || (!mOgreRenderTexture))
693 {
694 // Check if mWindow size has changed. Re-generate render texture if needed.
695 // forceUpdate recreate the texture
696 UpdateBufferSize();
697
698 // Update render texture
699 if (mOgreRenderTexture)
700 {
701 try
702 {
703 mOgreRenderTexture->update();
704
705 //create the DebugSelector directory to use
706 //mOgreRenderTexture->writeContentsToTimestampedFile("./DebugSelector/", ".bmp");
707 }
708 catch(Ogre::Exception)
709 {
710 }
711 }
712 }*/
713}
714
715void SSubEntitySelectorBuffer::UpdateBufferSize(const bool& forceRefresh)
716{
717 unsigned int newWidth = mOgreRenderWindow->getWidth();
718 unsigned int newHeight = mOgreRenderWindow->getHeight();
719
720 if ((newWidth != mRealWidth)
721 ||(newHeight != mRealHeight)
722 ||forceRefresh
723 ||(!mOgreRenderTexture))
724 {
725 DeleteTexture();
726 try
727 {
728 CreateTexture(newWidth, newHeight);
729 }
730 catch(Ogre::Exception &)
731 {
732 // could not create the texture, renderer not ready ?
733 }
734 }
735}
736
737void SSubEntitySelectorBuffer::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
738{
739 if (nodeSelectorMaterialSwitcher)
740 {
741 if (evt.source == mOgreRenderTexture || evt.source == mMrtTexture)
742 {
743 // Reset switcher
744 nodeSelectorMaterialSwitcher->ResetSwitcher();
745
746 //Get a list of non polygon solid camera
747 SelectorViewportList::iterator iOgreViewportList = mSelectorViewportList.begin();
748 while(iOgreViewportList != mSelectorViewportList.end())
749 {
750 SViewPort* viewport = iOgreViewportList->first;
751 SCamera* camera = viewport->GetCamera();
752 if(camera)
753 {
754 // Store camera that renders non-solid objects
755 Ogre::Camera* ogreWindowCamera = camera->GetOgreCameraPointer();
756 if (ogreWindowCamera->getPolygonMode() != Ogre::PM_SOLID)
757 {
758 mWireCameraList[ogreWindowCamera] = ogreWindowCamera->getPolygonMode();
759 ogreWindowCamera->setPolygonMode(Ogre::PM_SOLID);
760 }
761
762 // Force viewport to Rtt viewport
763 ogreWindowCamera->_notifyViewport(iOgreViewportList->second);
764 }
765
766 iOgreViewportList++;
767 }
768 }
769
770 Ogre::MaterialManager::getSingleton().addListener(nodeSelectorMaterialSwitcher, mBaseResourceName);
771 }
772}
773
774void SSubEntitySelectorBuffer::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
775{
776 if (((evt.source == mOgreRenderTexture) && mOgreRenderTexture->isActive()) || ((evt.source == mMrtTexture) && mMrtTexture->isActive()))
777 {
778 // Restore viewport to render mWindow's viewport (otherwise, the Ogre::Camera class member named mLastViewport is not coherent!).
779 SelectorViewportList::iterator iOgreViewportList = mSelectorViewportList.begin();
780 while(iOgreViewportList != mSelectorViewportList.end())
781 {
782 if (iOgreViewportList->second && iOgreViewportList->second->getCamera())
783 iOgreViewportList->second->getCamera()->_notifyViewport(iOgreViewportList->first->GetOgreViewPortPointer());
784 iOgreViewportList++;
785 }
786
787 // Restore list of non solid polygon camera
788 WireCameraList::iterator iWireCameraList = mWireCameraList.begin();
789 while(iWireCameraList != mWireCameraList.end())
790 {
791 iWireCameraList->first->setPolygonMode(iWireCameraList->second);
792 iWireCameraList++;
793 }
794 mWireCameraList.clear();
795
796 if (nodeSelectorMaterialSwitcher)
797 nodeSelectorMaterialSwitcher->ResetPriorizedObject();
798 }
799
800 if (nodeSelectorMaterialSwitcher)
801 Ogre::MaterialManager::getSingleton().removeListener(nodeSelectorMaterialSwitcher, mBaseResourceName);
802}
803
804}
Ogre::Camera * GetOgreCameraPointer()
Definition SO3Camera.cpp:50
std::string GetName() const
bool GetRttPixelFormat(Ogre::PixelFormat &format, bool alpha=false, bool floattex=false)
Definition SO3Root.cpp:650
Ogre::RenderSystem * GetOgreRenderSystem()
Definition SO3Root.cpp:865
static SRoot & getSingleton()
Definition SO3Root.cpp:116
static SRoot * getSingletonPtr()
Definition SO3Root.cpp:111
void UpdateBufferSize(const bool &forceRefresh)
void RemoveViewport(SViewPort *existingViewport)
virtual void preRenderTargetUpdate(const Ogre::RenderTargetEvent &evt)
void AddViewport(SViewPort *newViewport)
virtual void postRenderTargetUpdate(const Ogre::RenderTargetEvent &evt)
Ogre::SubEntity * GetSelectedSubEntity(int posX, int posY)
Ogre::SubEntity * GetSubEntity(const Ogre::ColourValue &searchedColour)
SCamera * GetCamera()
Ogre::RenderWindow * GetOgreRenderWindowPointer()