SO3Engine
SO3Root.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
31#include "SO3Renderer/SO3Root.h"
35
36#ifdef SO3_FLASH_ENABLE
38#endif
39
43
44#ifdef SO3_BUILD_DEFERRED
46#endif
47
52#include "SO3Material/SO3Pass.h"
66#include "SCOLPack/SO3SCOL.h"
67
68#include <OgreMeshLodGenerator.h>
69
70#ifdef _WIN32
71# ifndef SO3_USE_DX11
72 #include "OgreD3D9RenderWindow.h"
73 #include "OgreD3D9DeviceManager.h"
74# endif
75//#include <dxdiag.h>
76//#include "DSETUP.H"
77#endif
78
79
80#ifdef ANDROID
81 #include <EGL/egl.h>
82 #include <android/asset_manager.h>
83 #include <OgreGLRenderSystemCommon.h>
84#endif
85
86#include <boost/algorithm/string.hpp>
87#include <boost/lexical_cast.hpp>
88
89extern int SO3_LOGS_MSG;
90
91#ifdef _WIN32
92void(*SetRenderDeviceGetFunction)(std::function<void* ()> fptr);
93#endif
94
95/*
96//debug virtual call
97int __cdecl _purecall(void)
98{
99 return 0;
100}
101*/
102
103namespace Ogre
104{
105 template<> SRoot* Ogre::Singleton<SRoot>::msSingleton = 0;
106}
107
108namespace SO3
109{
110
112{
113 return msSingleton;
114}
115
117{
118 assert(msSingleton);
119 return (*msSingleton);
120}
121
122SRoot::SRoot(const std::string& firstPartition)
123{
124#ifdef _WIN32
125 SetRenderDeviceGetFunction = (void(__cdecl *)(std::function<void* ()>))SCgetExtra("SetRenderDeviceGetFunction");
127#endif
128
129 mShaderGenerator = 0;
130 mDeviceLost = true;
131 mPaused = false;
132 mResourcesReleased = false;
133 mUpdating = false;
134 mRendering = false;
135
136 //to make sure to have only an unique window name (used as group name in selector buffer)
137 windowIndex = 0;
138
139 // Initialise members.
140 renderSystem = SO3_NONE_RENDER_SYSTEM;
141 O3Render = 0;
142 fullScreenWindow = 0;
143 dummyWindow = 0;
144 defaultFsaa = "2";
145 quadBufferFocalLength = 1.0f;
146 quadBufferEyesSeparation = 0.06f;
147
148 O3OverlaySystem = 0;
149
150 mDebugEnable = false;
151 mDebugInitialized = false;
152 useVSync = false;
153 mDummyScene = 0;
154 mRootInitialised = false;
155 mSlicePlane = Ogre::Vector4(1.0f, 0.0f, 0.0f, 0.0f);
156 mSlicePlaneState = false;
157
158 // Ogre's plugins
159 staticPluginOctree = 0;
160
161#if !defined(ANDROID) && !defined(APPLE_IOS) && !defined(SO3_USE_METAL) && !defined(RPI)
162 staticPluginCG = 0;
163#endif
164 staticPluginParticleFX = 0;
165
166#ifdef SO3_BUILD_DEFERRED
167 //Deferred
168 deferredManager = 0;
169#endif
170
171 //Shader generator
172 mMaterialMgrListener = 0;
173
174 // Additionals plugins for Developper mode
175#ifdef SO3_DEVELOPPER_BUILD
176# ifdef _WIN32
177# ifndef SO3_USE_DX11
178 staticPluginD3D9 = 0;
179# else
180 staticPluginD3D11 = 0;
181# endif
182# endif
183
184# ifndef SO3_USE_OPENGLES2
185# ifdef SO3_USE_GL3
186 staticPluginOpenGL3 = 0;
187# elif !defined(SO3_USE_METAL)
188 staticPluginOpenGL = 0;
189# endif
190# elif !defined(SO3_USE_METAL)
191 staticPluginOpenGLES2 = 0;
192# endif
193
194# if defined(__APPLE__) && defined(SO3_USE_METAL)
195 staticPluginMetal = 0;
196# endif
197
198# if defined(_WIN64)
199 //staticPluginTiny = 0;
200
201 staticPluginVulkan = 0;
202 staticPluginGLSLang = 0;
203# endif
204#endif
205
206 // Creating Ogre's root object
207#if SO3_DEBUG
208# ifdef _WIN32
209 O3Root = OGRE_NEW Ogre::Root();
210# else
211 O3Root = OGRE_NEW Ogre::Root("", "");
212# endif
213#else
214 // No ogre log file for release builds
215 O3Root = OGRE_NEW Ogre::Root("", "", "");
216#endif
217
218 //do not wait too much in work queue
219 O3Root->getWorkQueue()->setMainThreadProcessingTimeLimit(4);
220
221 // Initialise SO3 Plugin system.
222 pluginManager = new SPluginManager();
223
224 // Initialise SO3 3D Widget Manager
225 widgetManager = new SWidgetManager();
226
227 // Add Bitmap widget support
228 bitmapWidgetFactory = new SBitmapWidgetFactory();
229 widgetManager->AddWidgetFactory(bitmapWidgetFactory);
230
231#ifdef _WIN32
232 // Add ObjWindow widget support
233 objWindowWidgetFactory = new SObjWindowWidgetFactory();
234 widgetManager->AddWidgetFactory(objWindowWidgetFactory);
235#endif
236
237#ifdef SO3_FLASH_ENABLE
238 // Add Flash widget support
239 flashWidgetFactory = new SFlashWidgetFactory();
240 widgetManager->AddWidgetFactory(flashWidgetFactory);
241#endif
242
243 // Add web navigator widget support
244 #if SO3_WEB_NAVIGATOR_BUILD == 1
245 ScolWindowHandle hwndScol = (ScolWindowHandle)SCgetExtra("hscol");
246
247 // Get the first partition as cache directory
248 std::string webBrowserCacheDir = firstPartition + std::string("tmp/CefCache");
249
250 // Add a subdirectory for the cache, in order to avoid messy files to go in the root partition dir
251 CreateDirectory(webBrowserCacheDir.c_str(), 0);
252
253 // Create the web navigator manager.
254 webNavigatorManager = new EmbeddedWebNavigator::WebNavigatorManager(hwndScol, webBrowserCacheDir);
255
256 // Create the web browser widget factory.
257 webNavigatorWidgetFactory = new SWebNavigatorWidgetFactory(hwndScol, firstPartition);
258 widgetManager->AddWidgetFactory(webNavigatorWidgetFactory);
259 #endif
260
261 keyboardHook = new SKeyboardHook();
262 // Load Ogre's plugins
263 LoadOgrePlugins();
264
265 mLogEnable = false;
266 Ogre::LogManager::getSingleton().getDefaultLog()->addListener((Ogre::LogListener*)this);
267
268 // Create Ogre's script resources loader
269 resourceLoader = new SResourceLoader();
270 Ogre::ScriptCompilerManager::getSingleton().setListener(resourceLoader);
271
272 // Load config file, this will select the Render system to use.
274
275 //init overlay system
276 O3OverlaySystem = new Ogre::OverlaySystem();
277
278#ifdef ANDROID
279 ScolWindowHandle win = (ScolWindowHandle)SCgetExtra("hscol");
280
281 mMainWidth = ANativeWindow_getWidth(win);
282 mMainHeight = ANativeWindow_getHeight(win);
283#endif
284
285 //init LOD generator
286 new Ogre::MeshLodGenerator();
287}
288
289#ifdef _WIN32
291{
292 Ogre::String rendererName = GetOgreRenderSystem()->getName();
293 if (rendererName != "Direct3D11 Rendering Subsystem")
294 return NULL;
295
296 Ogre::D3D11Device& device = static_cast<Ogre::D3D11RenderSystem*>(GetOgreRenderSystem())->_getDevice();
297 return (void*) device.get();
298}
299#endif
300
302{
303 return O3Root;
304}
305
307{
308 return mRootInitialised;
309}
310
311#ifdef SO3_BUILD_DEFERRED
313{
314 return deferredManager;
315}
316#endif
317
318void SRoot::ClearSceneManagerPassMaps()
319{
320 for (const auto& m : O3Root->getSceneManagers())
321 {
322 Ogre::SceneManager* pScene = m.second;
323 if (pScene)
324 {
325 Ogre::RenderQueue* pQueue = pScene->getRenderQueue();
326 if (pQueue)
327 {
328 pQueue->clear();
329 }
330 }
331 }
332}
333
334void SRoot::messageLogged(const Ogre::String& message, Ogre::LogMessageLevel lml, bool maskDebug, const Ogre::String &logName, bool& skipMessage)
335{
336 switch (lml)
337 {
338 case Ogre::LogMessageLevel::LML_CRITICAL:
339 case Ogre::LogMessageLevel::LML_NORMAL:
340 MMechostr(MSKRUNTIME, "%s\n", message.c_str());
341 break;
342 case Ogre::LogMessageLevel::LML_TRIVIAL:
343 MMechostr(MSKDEBUG, "%s\n", message.c_str());
344 break;
345 }
346
347 if (mLogEnable)
348 {
349 LogListenerList::iterator iLogListenerList = logListenerList.begin();
350 while(iLogListenerList != logListenerList.end())
351 {
352 (*iLogListenerList)->messageLogged(message);
353 iLogListenerList++;
354 }
355 }
356}
357
359{
360 if(logListenerList.count(newLogListener))
361 OGRE_EXCEPT(Ogre::Exception::ERR_DUPLICATE_ITEM, "Cannot add this listener, it already exists in the listener list!", "SRoot::AddLogListener");
362
363 logListenerList.insert(newLogListener);
364}
365
366void SRoot::RemoveLogListener(SLogListener* existingLogListener)
367{
368 if(!logListenerList.count(existingLogListener))
369 OGRE_EXCEPT(Ogre::Exception::ERR_DUPLICATE_ITEM, "Cannot remove listener, this listener does not exists in the listener list!", "SRoot::RemoveLogListener");
370
371 logListenerList.erase(existingLogListener);
372}
373
374void SRoot::SetLogEnable(const bool& state)
375{
376 mLogEnable = state;
377}
378
380{
381 return mLogEnable;
382}
383
384void SRoot::SetLogMask(const Ogre::LogMessageLevel& level)
385{
386 Ogre::LogManager::getSingleton().getDefaultLog()->setMinLogLevel(level);
387}
388
389bool SRoot::checkFSAA(const Ogre::String& value)
390{
391 bool finded = false;
392 Ogre::String val = value;
393 if(value.find("[Quality]") != string::npos)
394 val = value.substr(0, value.find("[Quality]")-2);
395
396 Ogre::ConfigOptionMap m_system_caps = this->O3Root->getRenderSystem()->getConfigOptions();
397 Ogre::ConfigOptionMap::iterator itr = m_system_caps.begin();
398 while(itr != m_system_caps.end()&&!finded)
399 {
400 if(itr->first == "FSAA" )
401 {
402 Ogre::StringVector possible_values = (itr)->second.possibleValues;
403 Ogre::StringVector::iterator pv_itr = possible_values.begin();
404 while(pv_itr != possible_values.end() && !finded)
405 {
406 if(!strcmp(val.c_str(),pv_itr->c_str()))
407 finded = true;
408 pv_itr++;
409 }
410 }
411 itr ++;
412 }
413 return finded;
414}
415
417{
419 SSceneMap::iterator iScene = sceneList.begin();
420 while (iScene != sceneList.end())
421 {
422 DeleteScene(iScene->second);
423 iScene++;
424 }
425
426 if (Ogre::MeshLodGenerator::getSingletonPtr())
427 delete Ogre::MeshLodGenerator::getSingletonPtr();
428
429 mSlicePlaneParams.reset();
430 mCommonParams.reset();
431 destroyRTShaderSystem();
432
434
437
439
440 if (O3Root->getRenderSystem())
441 O3Root->getRenderSystem()->removeListener(this);
442
443 SAFE_DELETE(O3OverlaySystem);
444
445 // Delete the keyboard hook
446 MMechostr(MSKDEBUG, "SO3Root cleanup : keyboardHook");
447 SO3_SAFE_DELETE(keyboardHook);
448
449#ifdef SO3_BUILD_DEFERRED
450 // Unload deferred shading manager
451 MMechostr(MSKDEBUG, "SO3Root cleanup : deferredManager");
452 SO3_SAFE_DELETE(deferredManager);
453#endif
454
455 // Unload SO3's plugins
456 MMechostr(MSKDEBUG, "SO3Root cleanup : pluginManager");
457 SO3_SAFE_DELETE(pluginManager);
458
459 // Delete SO3's Managers
460 MMechostr(MSKDEBUG, "SO3Root cleanup : widgetManager");
461 SO3_SAFE_DELETE(widgetManager);
462
463#ifdef _WIN32
464 // Delete obj window widget support (already remove from widget factory list by SWidgetManager destructor);
465 MMechostr(MSKDEBUG, "SO3Root cleanup : objWindowWidgetFactory");
466 SO3_SAFE_DELETE(objWindowWidgetFactory);
467#endif
468
469#ifdef SO3_FLASH_ENABLE
470 // Delete flash widget support (already remove from widget factory list by SWidgetManager destructor);
471 MMechostr(MSKDEBUG, "SO3Root cleanup : flashWidgetFactory");
472 SO3_SAFE_DELETE(flashWidgetFactory);
473#endif
474
475 // Delete bitmap widget support (already remove from widget factory list by SWidgetManager destructor);
476 MMechostr(MSKDEBUG, "SO3Root cleanup : bitmapWidgetFactory");
477 SO3_SAFE_DELETE(bitmapWidgetFactory);
478
479 // Delete web navigator widget support (already remove from widget factory list by SWidgetManager destructor);
480 #if SO3_WEB_NAVIGATOR_BUILD == 1
481 // Delete widget factory
482 MMechostr(MSKDEBUG, "SO3Root cleanup : webNavigatorWidgetFactory");
483 SO3_SAFE_DELETE(webNavigatorWidgetFactory);
484
485 // Destroy web manager
486 MMechostr(MSKDEBUG, "SO3Root cleanup : webNavigatorManager");
488 #endif
489
490 MMechostr(MSKDEBUG, "SO3Root cleanup : LogListener");
491 Ogre::LogManager::getSingleton().getDefaultLog()->removeListener((Ogre::LogListener*)this);
492
493 //destroy dummy window
494 MMechostr(MSKDEBUG, "SO3Root cleanup : dummyWindow");
495 if (dummyWindow)
496 {
497 SRoot::getSingleton().GetOgreRenderSystem()->destroyRenderWindow(dummyWindow->getName());
498 dummyWindow = 0;
499 }
500
502
503 try
504 {
505 Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup(SO3_INTERNAL_RESOURCE_GROUP);
506 Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup(SO3_INTERNAL_DYNAMIC_RESOURCE_GROUP);
507 Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup(SO3_INTERNAL_DYNAMIC_READABLE_RESOURCE_GROUP);
508 Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup(SO3_INTERNAL_HYDRAX_RESOURCE_GROUP);
509 Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup(SO3_INTERNAL_SKYX_RESOURCE_GROUP);
510 Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup(SO3_INTERNAL_SUBENTITY_SELECTOR_RESOURCE_GROUP);
511 }
512 catch (Ogre::Exception &e)
513 {
514 MMechostr(MSKRUNTIME, "SO3Root error: %s\n", e.getFullDescription().c_str());
515 }
516
517 // Destroy the resource loader
518 MMechostr(MSKDEBUG, "SO3Root cleanup : resourceLoader");
519 Ogre::ScriptCompilerManager::getSingleton().setListener(0);
520 SO3_SAFE_DELETE(resourceLoader);
521
522
523
524 // Destroy Ogre's root instance. NB that the destructor manage the plugins unloading on it's own.
525 MMechostr(MSKDEBUG, "SO3Root cleanup : O3Root");
526 SO3_SAFE_DELETE(O3Root);
527
528 // Only useful if Ogre is statically linked, to destroy plugins instance. Do nothing if linked as a dll.
529 MMechostr(MSKDEBUG, "SO3Root cleanup : UnloadOgrePlugins");
530 UnloadOgrePlugins();
531
532 MMechostr(MSKDEBUG, "SO3Root cleanup : Done");
533}
534
535SScene* SRoot::CreateScene(const std::string& newSceneName)
536{
537 SScene* newScene = new SScene(this, newSceneName);
538 AddScene(newScene);
539 return newScene;
540}
541
542void SRoot::DeleteScene(SScene* existingScene)
543{
544 RemoveScene(existingScene);
545
546 ClearSceneManagerPassMaps();
547
548 SO3_SAFE_DELETE(existingScene);
549}
550
551SScene* SRoot::GetScene(const std::string& sceneName)
552{
553 SSceneMap::iterator iSceneSearched = sceneList.find(sceneName);
554 if(iSceneSearched != sceneList.end())
555 return iSceneSearched->second;
556 else
557 return 0;
558}
559
561{
562 return sceneList;
563}
564
565void SRoot::AddScene(SScene* existingScene)
566{
567 string sceneName = existingScene->GetName();
568 SSceneMap::iterator iSceneSearched = sceneList.find(sceneName);
569 if(iSceneSearched == sceneList.end())
570 {
571 sceneList.insert(SSceneMap::value_type(sceneName, existingScene));
572 existingScene->GetOgreScenePointer()->addRenderQueueListener(O3OverlaySystem);
573
574 //debug overlay
575 if (mDebugEnable)
576 existingScene->SetDebugEnable(true);
577 }
578 else
579 {
580 // Scene already exist in the handled scenes list.
581 OGRE_EXCEPT(Ogre::Exception::ERR_DUPLICATE_ITEM, "Can not add Scene named \""+ sceneName +"\", an element with the same name already exist!", "SRoot::AddScene");
582 }
583}
584
585void SRoot::RemoveScene(SScene* existingScene)
586{
587 existingScene->GetOgreScenePointer()->removeRenderQueueListener(O3OverlaySystem);
588
589 RemoveScene(existingScene->GetName());
590}
591
592void SRoot::RemoveScene(const std::string& sceneName)
593{
594 SSceneMap::iterator iSceneSearched = sceneList.find(sceneName);
595 if(iSceneSearched != sceneList.end())
596 {
597 sceneList.erase(iSceneSearched);
598 }
599 else
600 {
601 // Scene not found in the handled scenes list
602 OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, "Can not remove Scene named \""+ sceneName +"\", element not found!", "SRoot::RemoveScene");
603 }
604}
605
606
607void SRoot::AddManualRessourceGroup(std::string name)
608{
609 try
610 {
611 Ogre::ResourceGroupManager::getSingleton().createResourceGroup(name, false);
612 mManualGroups.push_back(name);
613 }
614 catch (Ogre::Exception &e)
615 {
616 MMechostr(MSKRUNTIME, "AddManualRessourceGroup error: %s\n", e.getFullDescription().c_str());
617 }
618}
619
621{
622 try
623 {
624 Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup(name);
625 mManualGroups.remove(name);
626 }
627 catch (Ogre::Exception &e)
628 {
629 MMechostr(MSKRUNTIME, "RemoveManualRessourceGroup error: %s\n", e.getFullDescription().c_str());
630 }
631}
632
634{
635 for (manualGroupList::iterator it = mManualGroups.begin(); it != mManualGroups.end(); it++)
636 {
637 try
638 {
639 Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup(*it);
640 }
641 catch (Ogre::Exception &)
642 {
643 }
644 }
645
646 mManualGroups.clear();
647}
648
649
650bool SRoot::GetRttPixelFormat(Ogre::PixelFormat &format, bool alpha, bool floattex)
651{
652 if (floattex && !alpha)
653 {
654 if (Ogre::TextureManager::getSingleton().isFormatSupported(Ogre::TEX_TYPE_2D, Ogre::PF_FLOAT32_RGB, Ogre::TU_RENDERTARGET))
655 {
656 format = Ogre::PF_FLOAT32_RGB;
657 return true;
658 }
659 else if (Ogre::TextureManager::getSingleton().isFormatSupported(Ogre::TEX_TYPE_2D, Ogre::PF_FLOAT16_RGB, Ogre::TU_RENDERTARGET))
660 {
661 format = Ogre::PF_FLOAT16_RGB;
662 return true;
663 }
664 else if (Ogre::TextureManager::getSingleton().isFormatSupported(Ogre::TEX_TYPE_2D, Ogre::PF_FLOAT32_GR, Ogre::TU_RENDERTARGET))
665 {
666 format = Ogre::PF_FLOAT32_GR;
667 return true;
668 }
669 else if (Ogre::TextureManager::getSingleton().isFormatSupported(Ogre::TEX_TYPE_2D, Ogre::PF_FLOAT16_GR, Ogre::TU_RENDERTARGET))
670 {
671 format = Ogre::PF_FLOAT16_GR;
672 return true;
673 }
674 else if (Ogre::TextureManager::getSingleton().isFormatSupported(Ogre::TEX_TYPE_2D, Ogre::PF_FLOAT32_R, Ogre::TU_RENDERTARGET))
675 {
676 format = Ogre::PF_FLOAT32_R;
677 return true;
678 }
679 else if (Ogre::TextureManager::getSingleton().isFormatSupported(Ogre::TEX_TYPE_2D, Ogre::PF_FLOAT16_R, Ogre::TU_RENDERTARGET))
680 {
681 format = Ogre::PF_FLOAT16_R;
682 return true;
683 }
684
685 return false;
686 }
687
688 if (floattex)
689 {
690 if (Ogre::TextureManager::getSingleton().isFormatSupported(Ogre::TEX_TYPE_2D, Ogre::PF_FLOAT32_RGBA, Ogre::TU_RENDERTARGET))
691 {
692 format = Ogre::PF_FLOAT32_RGBA;
693 return true;
694 }
695 else if (Ogre::TextureManager::getSingleton().isFormatSupported(Ogre::TEX_TYPE_2D, Ogre::PF_FLOAT16_RGBA, Ogre::TU_RENDERTARGET))
696 {
697 format = Ogre::PF_FLOAT16_RGBA;
698 return true;
699 }
700 else if (Ogre::TextureManager::getSingleton().isFormatSupported(Ogre::TEX_TYPE_2D, Ogre::PF_R11G11B10_FLOAT, Ogre::TU_RENDERTARGET))
701 {
702 format = Ogre::PF_R11G11B10_FLOAT;
703 return true;
704 }
705 else if (Ogre::TextureManager::getSingleton().isFormatSupported(Ogre::TEX_TYPE_2D, Ogre::PF_FLOAT32_GR, Ogre::TU_RENDERTARGET))
706 {
707 format = Ogre::PF_FLOAT32_GR;
708 return true;
709 }
710 else if (Ogre::TextureManager::getSingleton().isFormatSupported(Ogre::TEX_TYPE_2D, Ogre::PF_FLOAT16_GR, Ogre::TU_RENDERTARGET))
711 {
712 format = Ogre::PF_FLOAT16_GR;
713 return true;
714 }
715
716 return false;
717 }
718
719 if (!alpha)
720 {
721 if (Ogre::TextureManager::getSingleton().isFormatSupported(Ogre::TEX_TYPE_2D, Ogre::PF_R8G8B8, Ogre::TU_RENDERTARGET))
722 {
723 format = Ogre::PF_R8G8B8;
724 return true;
725 }
726 else if (Ogre::TextureManager::getSingleton().isFormatSupported(Ogre::TEX_TYPE_2D, Ogre::PF_B8G8R8, Ogre::TU_RENDERTARGET))
727 {
728 format = Ogre::PF_B8G8R8;
729 return true;
730 }
731 }
732
733 //forget alpha optim
734 if (Ogre::TextureManager::getSingleton().isFormatSupported(Ogre::TEX_TYPE_2D, Ogre::PF_A8R8G8B8, Ogre::TU_RENDERTARGET))
735 {
736 format = Ogre::PF_A8R8G8B8;
737 return true;
738 }
739 else if (Ogre::TextureManager::getSingleton().isFormatSupported(Ogre::TEX_TYPE_2D, Ogre::PF_A8B8G8R8, Ogre::TU_RENDERTARGET))
740 {
741 format = Ogre::PF_A8B8G8R8;
742 return true;
743 }
744 else if (Ogre::TextureManager::getSingleton().isFormatSupported(Ogre::TEX_TYPE_2D, Ogre::PF_R8G8B8A8, Ogre::TU_RENDERTARGET))
745 {
746 format = Ogre::PF_R8G8B8A8;
747 return true;
748 }
749 else if (Ogre::TextureManager::getSingleton().isFormatSupported(Ogre::TEX_TYPE_2D, Ogre::PF_B8G8R8A8, Ogre::TU_RENDERTARGET))
750 {
751 format = Ogre::PF_B8G8R8A8;
752 return true;
753 }
754 else if (Ogre::TextureManager::getSingleton().isFormatSupported(Ogre::TEX_TYPE_2D, Ogre::PF_X8R8G8B8, Ogre::TU_RENDERTARGET))
755 {
756 format = Ogre::PF_X8R8G8B8;
757 return true;
758 }
759 else if (Ogre::TextureManager::getSingleton().isFormatSupported(Ogre::TEX_TYPE_2D, Ogre::PF_X8B8G8R8, Ogre::TU_RENDERTARGET))
760 {
761 format = Ogre::PF_X8B8G8R8;
762 return true;
763 }
764
765 return false;
766}
767
768SWindow* SRoot::CreateRenderWindow(const ScolWindowHandle windowHandle, const std::string& windowName, const int& width, const int& height, const std::string& renderWindowFsaa)
769{
770 std::string newWindowName = windowName + "_" + boost::lexical_cast<std::string, unsigned int>(++windowIndex);
771 SWindow* newWindow = 0;
772 if(renderWindowFsaa == "default")
773 newWindow = new SWindow(this, windowHandle, newWindowName, width, height, defaultFsaa);
774 else
775 newWindow = new SWindow(this, windowHandle, newWindowName, width, height, renderWindowFsaa);
776
777#if SO3_PROFILER == 1
778 Ogre::Profiler* prof = Ogre::Profiler::getSingletonPtr();
779 if (prof)
780 prof->setEnabled(true);
781#endif
782
783 AddRenderWindow(newWindow);
784 return newWindow;
785}
786
788{
789 if (fullScreenWindow == existingWindow)
790 fullScreenWindow = 0;
791
792 RemoveRenderWindow(existingWindow);
793 SO3_SAFE_DELETE(existingWindow);
794}
795
796SWindow* SRoot::GetRenderWindow(const ScolWindowHandle& hwnd)
797{
798 SWindow* winfound = 0;
799 const SWindowMap lWin = windowList;
800 SWindowMap::const_iterator iWindowSearched = lWin.begin();
801
802 while((iWindowSearched != lWin.end()) && (winfound == 0))
803 {
804 if (iWindowSearched->second->GetWindowHandle() == hwnd)
805 winfound = iWindowSearched->second;
806 iWindowSearched++;
807 }
808
809 return winfound;
810}
811
812SWindow* SRoot::GetRenderWindow(const std::string& windowName)
813{
814 SWindowMap::iterator iWindowSearched = windowList.find(windowName);
815 if(iWindowSearched != windowList.end())
816 return iWindowSearched->second;
817 else
818 return 0;
819}
820
822{
823 return windowList;
824}
825
826void SRoot::AddRenderWindow(SWindow* existingWindow)
827{
828 string windowName = existingWindow->GetName();
829 SWindowMap::iterator iWindowSearched = windowList.find(windowName);
830 if(iWindowSearched == windowList.end())
831 {
832 windowList.insert(SWindowMap::value_type(windowName, existingWindow));
833 }
834 else
835 {
836 // Scene already exist in the handled scenes list.
837 OGRE_EXCEPT(Ogre::Exception::ERR_DUPLICATE_ITEM, "Can not add Window named \""+ windowName +"\", an element with the same name already exist!", "SRoot::AddWindow");
838 }
839}
840
842{
843 RemoveRenderWindow(existingWindow->GetName());
844}
845
846void SRoot::RemoveRenderWindow(const std::string& windowName)
847{
848 SWindowMap::iterator iWindowSearched = windowList.find(windowName);
849 if(iWindowSearched != windowList.end())
850 {
851 windowList.erase(iWindowSearched);
852 }
853 else
854 {
855 // Window not found in the handled windows list
856 OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, "Can not remove Window named \""+ windowName +"\", element not found!", "SRoot::RemoveWindow");
857 }
858}
859
861{
862 return renderSystem;
863}
864
865Ogre::RenderSystem* SRoot::GetOgreRenderSystem()
866{
867 return O3Render;
868}
869
870void SRoot::SetRenderSystem(const RenderSystem& selectedRenderSystem, const bool& activateQuadBuffer)
871{
872 if (selectedRenderSystem == SO3_NONE_RENDER_SYSTEM)
873 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "Cannot set render system to \"none\", invalid render system.", "SRoot::SetRenderSystem");
874
875 if (renderSystem != SO3_NONE_RENDER_SYSTEM)
876 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "Render system is still setted, cannot change render system while running.", "SRoot::SetRenderSystem");
877
878 // If our ogre is anterior to v1.7
879 #if OGRE_VERSION < ((1 << 16) | (7 << 8) | 0)
880 Ogre::RenderSystemList* renderSystemList = O3Root->getAvailableRenderers();
881 if(renderSystemList == NULL)
882 #else
883 const Ogre::RenderSystemList renderSystemList = O3Root->getAvailableRenderers();
884 if(renderSystemList.empty())
885 #endif
886 OGRE_EXCEPT(Ogre::Exception::ERR_INTERNAL_ERROR, "No supported render system found!", "SRoot::SetRenderSystem");
887
888 // TODO: check if a correct render system exists before???
889 try
890 {
891 switch(selectedRenderSystem)
892 {
894 O3Render = O3Root->getRenderSystemByName("Direct3D9 Rendering Subsystem");
895 renderSystem = selectedRenderSystem;
896
897 // Set render system options
898 O3Render->setConfigOption("Use Multihead", "Auto");
899 O3Render->setConfigOption("Resource Creation Policy", "Create on all devices");
900 O3Render->setConfigOption("Auto hardware buffer management", "Yes");
901 //O3Render->setConfigOption("Allow DirectX9Ex", "Yes");
902 break;
904 O3Render = O3Root->getRenderSystemByName("Direct3D11 Rendering Subsystem");
905 //O3Render->setConfigOption("Debug Layer", "On");
906 renderSystem = selectedRenderSystem;
907 break;
909 O3Render = O3Root->getRenderSystemByName("Vulkan Rendering Subsystem");
910 renderSystem = selectedRenderSystem;
911 break;
913 O3Render = O3Root->getRenderSystemByName("Tiny Rendering Subsystem");
914 renderSystem = selectedRenderSystem;
915 break;
917 O3Render = O3Root->getRenderSystemByName("Metal Rendering Subsystem");
918 renderSystem = selectedRenderSystem;
919 break;
921 #ifndef SO3_USE_OPENGLES2
922 #ifndef SO3_USE_GL3
923 O3Render = O3Root->getRenderSystemByName("OpenGL Rendering Subsystem");
924 try
925 {
926 if (activateQuadBuffer)
927 {
928 MMechostr(MSKRUNTIME, "Rendering Stereo mode : QuadBuffer\n");
929 O3Render->setConfigOption("Stereo Mode", "QuadBuffer");
930 }
931 else
932 {
933 MMechostr(MSKRUNTIME, "Rendering Stereo mode : Mono\n");
934 O3Render->setConfigOption("Stereo Mode", "Mono");
935 }
936 }
937 catch (Ogre::Exception &)
938 {
939 MMechostr(MSKRUNTIME, "Rendering Stereo mode : Not supported\n");
940 }
941 #else
942 O3Render = O3Root->getRenderSystemByName("OpenGL 3+ Rendering Subsystem");
943 #endif
944 #else
945 O3Render = O3Root->getRenderSystemByName("OpenGL ES 2.x Rendering Subsystem");
946 #endif
947 renderSystem = selectedRenderSystem;
948 break;
949 }
950
951 if (!O3Render)
952 {
953 renderSystem = SO3_OPENGL_RENDERER;
954#ifndef SO3_USE_OPENGLES2
955#ifndef SO3_USE_GL3
956 O3Render = O3Root->getRenderSystemByName("OpenGL Rendering Subsystem");
957#else
958 O3Render = O3Root->getRenderSystemByName("OpenGL 3+ Rendering Subsystem");
959#endif
960#else
961 O3Render = O3Root->getRenderSystemByName("OpenGL ES 2.x Rendering Subsystem");
962#endif
963 }
964
965 O3Root->setRenderSystem(O3Render);
966 }
967 catch(Ogre::Exception&)
968 {
969 // TO VERIFY
970 renderSystem = SO3_OPENGL_RENDERER;
971 #ifndef SO3_USE_OPENGLES2
972 #ifndef SO3_USE_GL3
973 O3Render = O3Root->getRenderSystemByName("OpenGL Rendering Subsystem");
974 #else
975 O3Render = O3Root->getRenderSystemByName("OpenGL 3+ Rendering Subsystem");
976 #endif
977 #else
978 O3Render = O3Root->getRenderSystemByName("OpenGL ES 2.x Rendering Subsystem");
979 #endif
980 O3Root->setRenderSystem(O3Render);
981 }
982
983 //Saw that somewhere about depth buffer
984 //O3Render->setConfigOption("Floating-point mode", "Consistent");
985
986 O3Root->getSingleton().initialise(false);
987 mDeviceLost = false;
988
989 O3Root->getRenderSystem()->addListener(this);
990}
991
992std::vector<std::string> SRoot::GetMultisamplingMode(const RenderSystem& wishedRenderSystem)
993{
994 if (wishedRenderSystem == SO3_NONE_RENDER_SYSTEM)
995 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "Cannot get render system multisampling information for \"none\", invalid render system.", "SRoot::GetMultisamplingMode");
996
997 Ogre::RenderSystem* selectedRenderSystem = 0;
998 std::vector<std::string> multisamplingModes;
999
1000 try
1001 {
1002 switch(wishedRenderSystem)
1003 {
1006 #ifndef SO3_USE_DX11
1007 selectedRenderSystem = O3Root->getRenderSystemByName("Direct3D9 Rendering Subsystem");
1008 #else
1009 selectedRenderSystem = O3Root->getRenderSystemByName("Direct3D11 Rendering Subsystem");
1010 #endif
1011 break;
1013 selectedRenderSystem = O3Root->getRenderSystemByName("Vulkan Rendering Subsystem");
1014 case SO3_TINY_RENDERER:
1015 selectedRenderSystem = O3Root->getRenderSystemByName("Tiny Rendering Subsystem");
1016 case SO3_METAL_RENDERER:
1017 selectedRenderSystem = O3Root->getRenderSystemByName("Metal Rendering Subsystem");
1019 #ifndef SO3_USE_OPENGLES2
1020 #ifndef SO3_USE_GL3
1021 selectedRenderSystem = O3Root->getRenderSystemByName("OpenGL Rendering Subsystem");
1022 #else
1023 selectedRenderSystem = O3Root->getRenderSystemByName("OpenGL 3+ Rendering Subsystem");
1024 #endif
1025 #else
1026 selectedRenderSystem = O3Root->getRenderSystemByName("OpenGL ES 2.x Rendering Subsystem");
1027 #endif
1028 break;
1029 }
1030 }
1031 catch (Ogre::Exception &)
1032 {
1033 #ifndef SO3_USE_OPENGLES2
1034 #ifndef SO3_USE_GL3
1035 selectedRenderSystem = O3Root->getRenderSystemByName("OpenGL Rendering Subsystem");
1036 #else
1037 selectedRenderSystem = O3Root->getRenderSystemByName("OpenGL 3+ Rendering Subsystem");
1038 #endif
1039 #else
1040 selectedRenderSystem = O3Root->getRenderSystemByName("OpenGL ES 2.x Rendering Subsystem");
1041 #endif
1042 }
1043
1044 if (selectedRenderSystem != 0)
1045 {
1046 Ogre::ConfigOptionMap m_system_caps = selectedRenderSystem->getConfigOptions();
1047 Ogre::ConfigOptionMap::iterator itr = m_system_caps.find("FSAA");
1048 if (itr == m_system_caps.end())
1049 itr = m_system_caps.find("Anti aliasing");
1050
1051 if (itr != m_system_caps.end())
1052 {
1053 Ogre::StringVector possible_values = itr->second.possibleValues;
1054 Ogre::StringVector::iterator pv_itr = possible_values.begin();
1055 while (pv_itr != possible_values.end())
1056 {
1057 multisamplingModes.push_back(*pv_itr);
1058 pv_itr++;
1059 }
1060 }
1061 }
1062
1063 return multisamplingModes;
1064}
1065
1067{
1068#ifdef _WIN32
1069/*
1070 bool directxOk = false;
1071 DWORD dwVersion;
1072 DWORD dwRevision;
1073 if(DirectXSetupGetVersion(&dwVersion, &dwRevision))
1074 {
1075 int a = (int)HIWORD(dwVersion);
1076 int b = (int)LOWORD(dwVersion);
1077 int c = (int)HIWORD(dwRevision);
1078 int d = (int)LOWORD(dwRevision);
1079
1080 if(b == 9 && d>= 904)
1081 directxOk = true;
1082 }
1083 return directxOk;
1084 */
1085 return true;
1086#else
1087 return false;
1088#endif
1089}
1090
1091bool SRoot::LoadOgrePlugins()
1092{
1093#ifdef SO3_DEVELOPPER_BUILD
1094# ifdef _WIN32
1095# ifndef SO3_USE_DX11
1096 // Create renderers here, as they will be statically builded.
1097 try
1098 {
1099 staticPluginD3D9 = OGRE_NEW Ogre::D3D9Plugin();
1100 Ogre::Root::getSingleton().installPlugin(staticPluginD3D9);
1101 }
1102 catch(Ogre::Exception&)
1103 {
1104 //error on plugin load
1105 MMechostr(MSKRUNTIME, "Error on D3D9 plugin load\n");
1106 }
1107# else
1108 try
1109 {
1110 staticPluginD3D11 = OGRE_NEW Ogre::D3D11Plugin();
1111 Ogre::Root::getSingleton().installPlugin(staticPluginD3D11);
1112 }
1113 catch(Ogre::Exception&)
1114 {
1115 //error on plugin load
1116 MMechostr(MSKRUNTIME, "Error on D3D11 plugin load\n");
1117 }
1118# endif
1119#endif
1120
1121#if !defined(SO3_USE_METAL)
1122 try
1123 {
1124# ifndef SO3_USE_OPENGLES2
1125# ifdef SO3_USE_GL3
1126 staticPluginOpenGL3 = OGRE_NEW Ogre::GL3PlusPlugin();
1127 Ogre::Root::getSingleton().installPlugin(staticPluginOpenGL3);
1128# elif !defined(SO3_USE_METAL)
1129 staticPluginOpenGL = OGRE_NEW Ogre::GLPlugin();
1130 Ogre::Root::getSingleton().installPlugin(staticPluginOpenGL);
1131# endif
1132# elif !defined(SO3_USE_METAL)
1133 staticPluginOpenGLES2 = OGRE_NEW Ogre::GLES2Plugin();
1134 Ogre::Root::getSingleton().installPlugin(staticPluginOpenGLES2);
1135# endif
1136 }
1137 catch(Ogre::Exception&)
1138 {
1139 //error on plugin load
1140 #ifndef SO3_USE_OPENGLES2
1141 MMechostr(MSKRUNTIME, "Error on OpenGL plugin load\n");
1142 #else
1143 MMechostr(MSKRUNTIME, "Error on OpenGLES2 plugin load\n");
1144 #endif
1145 }
1146#endif
1147
1148# if defined(__APPLE__) && defined(SO3_USE_METAL)
1149 try
1150 {
1151 staticPluginMetal = OGRE_NEW Ogre::MetalPlugin();
1152 Ogre::Root::getSingleton().installPlugin(staticPluginMetal);
1153 }
1154 catch (Ogre::Exception&)
1155 {
1156 //error on plugin load
1157 MMechostr(MSKRUNTIME, "Error on Metal renderer plugin load\n");
1158 }
1159# endif
1160
1161# if defined(_WIN64)
1162 //try
1163 //{
1164 // staticPluginTiny = OGRE_NEW Ogre::TinyPlugin();
1165 // Ogre::Root::getSingleton().installPlugin(staticPluginTiny);
1166 //}
1167 //catch (Ogre::Exception&)
1168 //{
1169 // //error on plugin load
1170 // MMechostr(MSKRUNTIME, "Error on Tiny renderer plugin load\n");
1171 //}
1172
1173 try
1174 {
1175 staticPluginVulkan = OGRE_NEW Ogre::VulkanPlugin();
1176 Ogre::Root::getSingleton().installPlugin(staticPluginVulkan);
1177 }
1178 catch (Ogre::Exception&)
1179 {
1180 //error on plugin load
1181 MMechostr(MSKRUNTIME, "Error on Vulkan renderer plugin load\n");
1182 }
1183
1184 try
1185 {
1186 staticPluginGLSLang = OGRE_NEW Ogre::GLSLangPlugin();
1187 Ogre::Root::getSingleton().installPlugin(staticPluginGLSLang);
1188 }
1189 catch (Ogre::Exception&)
1190 {
1191 //error on plugin load
1192 MMechostr(MSKRUNTIME, "Error on GLSLang plugin load\n");
1193 }
1194# endif
1195
1196# else
1197 // Load renderers as Ogre plugins
1198# ifdef SO3_DEBUG
1199 Ogre::Root::getSingleton().loadPlugin("plugins/SO3_RenderSystem_GL_d.dll");
1200 Ogre::Root::getSingleton().loadPlugin("plugins/SO3_RenderSystem_Direct3D9_d.dll");
1201# else
1202 Ogre::Root::getSingleton().loadPlugin("plugins/SO3_RenderSystem_GL.dll");
1203 Ogre::Root::getSingleton().loadPlugin("plugins/SO3_RenderSystem_Direct3D9.dll");
1204# endif
1205# endif
1206
1207 // Load others ogre plugins the same way (statically linking or internal build).
1208 try
1209 {
1210 staticPluginParticleFX = OGRE_NEW Ogre::ParticleFXPlugin();
1211 Ogre::Root::getSingleton().installPlugin(staticPluginParticleFX);
1212 }
1213 catch(Ogre::Exception&)
1214 {
1215 //error on plugin load
1216 MMechostr(MSKRUNTIME, "Error on Particle FX plugin load\n");
1217 }
1218
1219 //Start STBI Image codec plugin
1220 Ogre::STBIImageCodec::startup();
1221
1222#if !defined(ANDROID) && !defined(APPLE_IOS) && !defined(SO3_USE_METAL) && !defined(RPI)
1223 try
1224 {
1225 staticPluginCG = OGRE_NEW Ogre::CgPlugin();
1226 Ogre::Root::getSingleton().installPlugin(staticPluginCG);
1227 }
1228 catch(Ogre::Exception&)
1229 {
1230 //error on plugin load
1231 MMechostr(MSKRUNTIME, "Error on CG plugin load\n");
1232 }
1233#endif
1234
1235 try
1236 {
1237 staticPluginOctree = OGRE_NEW Ogre::OctreePlugin();
1238 Ogre::Root::getSingleton().installPlugin(staticPluginOctree);
1239 }
1240 catch(Ogre::Exception&)
1241 {
1242 //error on plugin load
1243 MMechostr(MSKRUNTIME, "Error on Octree plugin load\n");
1244 }
1245
1246
1247 // Adding Scol FileSystem Archive Manager to Ogre.
1248 scolFileSystemArchiveFactory = OGRE_NEW SO3ScolFileSystemArchiveFactory();
1249 Ogre::ArchiveManager::getSingleton().addArchiveFactory(scolFileSystemArchiveFactory);
1250
1251#ifdef ANDROID
1252 // Android archives
1253 struct android_app* androidApp = (struct android_app*)SCgetExtra("this_inst");
1254 if (androidApp != NULL)
1255 {
1256 Ogre::ArchiveManager::getSingleton().addArchiveFactory(new Ogre::APKFileSystemArchiveFactory(androidApp->activity->assetManager));
1257 Ogre::ArchiveManager::getSingleton().addArchiveFactory(new Ogre::APKZipArchiveFactory(androidApp->activity->assetManager));
1258 }
1259#endif
1260
1261 // All done!
1262 return true;
1263}
1264
1265bool SRoot::UnloadOgrePlugins()
1266{
1267 OGRE_DELETE scolFileSystemArchiveFactory;
1268 OGRE_DELETE staticPluginOctree;
1269
1270#if !defined(ANDROID) && !defined(APPLE_IOS) && !defined(SO3_USE_METAL) && !defined(RPI)
1271 OGRE_DELETE staticPluginCG;
1272#endif
1273
1274 OGRE_DELETE staticPluginParticleFX;
1275
1276 Ogre::STBIImageCodec::shutdown();
1277
1278# ifdef SO3_DEVELOPPER_BUILD
1279# ifdef _WIN32
1280# ifndef SO3_USE_DX11
1281 OGRE_DELETE staticPluginD3D9;
1282# else
1283 OGRE_DELETE staticPluginD3D11;
1284# endif
1285# endif
1286
1287# ifndef SO3_USE_OPENGLES2
1288# ifdef SO3_USE_GL3
1289 OGRE_DELETE staticPluginOpenGL3;
1290# elif !defined(SO3_USE_METAL)
1291 OGRE_DELETE staticPluginOpenGL;
1292# endif
1293# elif !defined(SO3_USE_METAL)
1294 OGRE_DELETE staticPluginOpenGLES2;
1295# endif
1296
1297# if defined(__APPLE__) && defined(SO3_USE_METAL)
1298 OGRE_DELETE staticPluginMetal;
1299# endif
1300
1301# if defined(_WIN64)
1302 //OGRE_DELETE staticPluginTiny;
1303 OGRE_DELETE staticPluginGLSLang;
1304 OGRE_DELETE staticPluginVulkan;
1305# endif
1306#endif
1307 return true;
1308}
1309
1311{
1312 // Initialize resource only once, right after the first window is created, otherwise Ogre is craching.
1313 if (dummyWindow == 0)
1314 {
1315 if (pwin == 0)
1316 {
1317 // Setting render window options
1318 Ogre::NameValuePairList viewConfig;
1319 viewConfig["hidden"] = "Yes";
1320 viewConfig["Resource Creation Policy"] = "Create on all devices";
1321 viewConfig["Multi device memory hint"] = "Auto hardware buffers management";
1322 viewConfig["vsync"] = "No";
1323
1324 dummyWindow = Ogre::Root::getSingleton().createRenderWindow("OgreDummyWindow", 1, 1, false, &viewConfig);
1325 dummyWindow->setAutoUpdated(false);
1326 dummyWindow->setDeactivateOnFocusChange(false);
1327 }
1328 else
1329 {
1330 dummyWindow = const_cast<Ogre::RenderWindow*>(pwin->GetOgreRenderWindowPointer());
1331 }
1332
1333 try
1334 {
1335 // add definitions for CSM shadows
1337
1338 // add slice plane GPU params
1339 mSlicePlaneParams = Ogre::GpuProgramManager::getSingleton().createSharedParameters("SO3SlicePlaneParams");
1340 mSlicePlaneParams->addConstantDefinition("slicePlane", Ogre::GCT_FLOAT4);
1341
1342 if (mSlicePlaneState)
1343 mSlicePlaneParams->setNamedConstant("slicePlane", mSlicePlane);
1344 else
1345 mSlicePlaneParams->setNamedConstant("slicePlane", Ogre::Vector4::ZERO);
1346
1347 //add camera DOF target GPU params
1348 mCommonParams = Ogre::GpuProgramManager::getSingleton().createSharedParameters("SO3CameraParams");
1349 mCommonParams->addConstantDefinition("cameraProjection", Ogre::GCT_FLOAT4);
1350 mCommonParams->setNamedConstant("cameraProjection", Ogre::Vector4::ZERO);
1351 mCommonParams->addConstantDefinition("cameraParams", Ogre::GCT_FLOAT4);
1352 mCommonParams->setNamedConstant("cameraParams", Ogre::Vector4::ZERO);
1353
1354 // Create an SO3 internal resource group
1355 // If our ogre is anterior to v1.7
1356 #if OGRE_VERSION < ((1 << 16) | (7 << 8) | 0)
1357 Ogre::ResourceGroupManager::getSingleton().createResourceGroup(SO3_INTERNAL_RESOURCE_GROUP);
1358 Ogre::ResourceGroupManager::getSingleton().createResourceGroup(SO3_INTERNAL_DYNAMIC_RESOURCE_GROUP);
1359 Ogre::ResourceGroupManager::getSingleton().createResourceGroup(SO3_INTERNAL_DYNAMIC_READABLE_RESOURCE_GROUP);
1360 Ogre::ResourceGroupManager::getSingleton().createResourceGroup(SO3_INTERNAL_HYDRAX_RESOURCE_GROUP);
1361 Ogre::ResourceGroupManager::getSingleton().createResourceGroup(SO3_INTERNAL_SKYX_RESOURCE_GROUP);
1362 Ogre::ResourceGroupManager::getSingleton().createResourceGroup(SO3_INTERNAL_SUBENTITY_SELECTOR_RESOURCE_GROUP);
1363
1364#ifdef SO3_BUILD_DEFERRED
1365 Ogre::ResourceGroupManager::getSingleton().createResourceGroup(SO3_INTERNAL_DEFERRED_RESOURCE_GROUP);
1366#endif
1367 #else
1368 Ogre::ResourceGroupManager::getSingleton().createResourceGroup(SO3_INTERNAL_RESOURCE_GROUP, false);
1369 Ogre::ResourceGroupManager::getSingleton().createResourceGroup(SO3_INTERNAL_DYNAMIC_RESOURCE_GROUP, false);
1370 Ogre::ResourceGroupManager::getSingleton().createResourceGroup(SO3_INTERNAL_DYNAMIC_READABLE_RESOURCE_GROUP, true);
1371 Ogre::ResourceGroupManager::getSingleton().createResourceGroup(SO3_INTERNAL_HYDRAX_RESOURCE_GROUP, true);
1372 Ogre::ResourceGroupManager::getSingleton().createResourceGroup(SO3_INTERNAL_SKYX_RESOURCE_GROUP, true);
1373 Ogre::ResourceGroupManager::getSingleton().createResourceGroup(SO3_INTERNAL_SUBENTITY_SELECTOR_RESOURCE_GROUP, true);
1374
1375#ifdef SO3_BUILD_DEFERRED
1376 Ogre::ResourceGroupManager::getSingleton().createResourceGroup(SO3_INTERNAL_DEFERRED_RESOURCE_GROUP, true);
1377#endif
1378 #endif
1379
1380 MMechostr(MSKDEBUG, ">> Add Ogre ressource locations\n");
1381
1382 #ifdef _WIN32
1383 /*#ifdef SO3_DEBUG
1384 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("Plugins/Ogre_Redist/OgreCore", "FileSystem", Ogre::RGN_INTERNAL, true);
1385 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("Plugins/Ogre_Redist/rtshaderlib", "FileSystem", Ogre::RGN_INTERNAL, true);
1386 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("Plugins/Ogre_Redist/Hydrax", "FileSystem", SO3_INTERNAL_HYDRAX_RESOURCE_GROUP, true);
1387 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("Plugins/Ogre_Redist/SkyX", "FileSystem", SO3_INTERNAL_SKYX_RESOURCE_GROUP, true);
1388 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("Plugins/Ogre_Redist/SO3SelectionBuffer", "FileSystem", SO3_INTERNAL_SUBENTITY_SELECTOR_RESOURCE_GROUP, true);
1389 #else*/
1390 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("Plugins/Ogre_Redist/OgreCore.zip", "Zip", Ogre::RGN_INTERNAL, true);
1391 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("Plugins/Ogre_Redist/rtshaderlib.zip", "Zip", Ogre::RGN_INTERNAL, true);
1392 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("Plugins/Ogre_Redist/SO3Core.zip", "Zip", SO3_INTERNAL_RESOURCE_GROUP, true);
1393 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("Plugins/Ogre_Redist/Hydrax.zip", "Zip", SO3_INTERNAL_HYDRAX_RESOURCE_GROUP, true);
1394 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("Plugins/Ogre_Redist/SkyX.zip", "Zip", SO3_INTERNAL_SKYX_RESOURCE_GROUP, true);
1395 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("Plugins/Ogre_Redist/SO3SelectionBuffer.zip", "Zip", SO3_INTERNAL_SUBENTITY_SELECTOR_RESOURCE_GROUP, true);
1396 //#endif
1397#ifdef SO3_BUILD_DEFERRED
1398 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("Plugins/Ogre_Redist/SO3Deferred.zip", "Zip", SO3_INTERNAL_DEFERRED_RESOURCE_GROUP, true);
1399#endif
1400 #elif defined(ANDROID)
1401 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("ogre_redist/ogrecore.zip", "APKZip", Ogre::RGN_INTERNAL, true);
1402 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("ogre_redist/rtshaderlib.zip", "APKZip", Ogre::RGN_INTERNAL, true);
1403 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("ogre_redist/so3core.zip", "APKZip", SO3_INTERNAL_RESOURCE_GROUP, true);
1404 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("ogre_redist/hydrax.zip", "APKZip", SO3_INTERNAL_HYDRAX_RESOURCE_GROUP, true);
1405 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("ogre_redist/skyx.zip", "APKZip", SO3_INTERNAL_SKYX_RESOURCE_GROUP, true);
1406 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("ogre_redist/so3selectionbuffer.zip", "APKZip", SO3_INTERNAL_SUBENTITY_SELECTOR_RESOURCE_GROUP, true);
1407 #elif defined(SO3_USE_OPENGLES2)
1408 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("ogre_redist/ogrecore.zip", "Zip", Ogre::RGN_INTERNAL, true);
1409 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("ogre_redist/rtshaderlib.zip", "Zip", Ogre::RGN_INTERNAL, true);
1410 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("ogre_redist/so3core.zip", "Zip", SO3_INTERNAL_RESOURCE_GROUP, true);
1411 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("ogre_redist/hydrax.zip", "Zip", SO3_INTERNAL_HYDRAX_RESOURCE_GROUP, true);
1412 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("ogre_redist/skyx.zip", "Zip", SO3_INTERNAL_SKYX_RESOURCE_GROUP, true);
1413 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("ogre_redist/so3selectionbuffer.zip", "Zip", SO3_INTERNAL_SUBENTITY_SELECTOR_RESOURCE_GROUP, true);
1414 #else //linux
1415 std::string baseDir = (char*)SCgetExtra("scolExecDir");
1416 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(baseDir + "/ogre_redist/ogrecore.zip", "Zip", Ogre::RGN_INTERNAL, true);
1417 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(baseDir + "/ogre_redist/rtshaderlib.zip", "Zip", Ogre::RGN_INTERNAL, true);
1418 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(baseDir + "/ogre_redist/so3core.zip", "Zip", SO3_INTERNAL_RESOURCE_GROUP, true);
1419 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(baseDir + "/ogre_redist/hydrax.zip", "Zip", SO3_INTERNAL_HYDRAX_RESOURCE_GROUP, true);
1420 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(baseDir + "/ogre_redist/skyx.zip", "Zip", SO3_INTERNAL_SKYX_RESOURCE_GROUP, true);
1421 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(baseDir + "/ogre_redist/so3selectionbuffer.zip", "Zip", SO3_INTERNAL_SUBENTITY_SELECTOR_RESOURCE_GROUP, true);
1422 #endif
1423
1424 initialiseRTShaderSystem();
1425
1426 // Initialise resources
1427 MMechostr(MSKDEBUG, ">> Initialise Ogre ressource groups\n");
1428 Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
1429
1430 const Ogre::GpuProgramManager::SyntaxCodes &syntaxCodes = Ogre::GpuProgramManager::getSingleton().getSupportedSyntax();
1431 for (Ogre::GpuProgramManager::SyntaxCodes::const_iterator iter = syntaxCodes.begin(); iter != syntaxCodes.end(); ++iter)
1432 {
1433 MMechostr(MSKDEBUG, ">>> Ogre Supported shader syntax %s\n", (*iter).c_str());
1434 }
1435
1436 //Override default materials
1437 Ogre::MaterialPtr defmat = Ogre::MaterialManager::getSingletonPtr()->getByName("BaseWhite", Ogre::RGN_INTERNAL);
1438 defmat->setAmbient(Ogre::ColourValue(0.5f, 0.5f, 0.5f, 1.0f));
1439 defmat->setDiffuse(Ogre::ColourValue::White);
1440 defmat->setSpecular(Ogre::ColourValue::White);
1441 defmat->setShininess(40.0f);
1442 defmat->getTechnique(0)->getPass(0)->setVertexProgram("SO3/Internal/Default_vp");
1443 defmat->getTechnique(0)->getPass(0)->setFragmentProgram("SO3/Internal/Default_fp");
1444 defmat->load();
1445
1446 Ogre::MaterialPtr defmatnolight = Ogre::MaterialManager::getSingletonPtr()->getByName("BaseWhiteNoLighting", Ogre::RGN_INTERNAL);
1447 defmatnolight->setAmbient(Ogre::ColourValue::White);
1448 defmatnolight->setDiffuse(Ogre::ColourValue::White);
1449 defmatnolight->setSpecular(Ogre::ColourValue::White);
1450 defmatnolight->setShininess(40.0f);
1451 defmatnolight->setReceiveShadows(false);
1452 defmatnolight->getTechnique(0)->getPass(0)->setVertexProgram("SO3/Internal/Default_nolight_vp");
1453 defmatnolight->getTechnique(0)->getPass(0)->setFragmentProgram("SO3/Internal/Default_fp");
1454 defmatnolight->load();
1455
1456 /* Creating debug resources */
1457 if (!mDebugInitialized)
1458 {
1459 // Create an helper mesh for bones.
1460 CreateBoneHelperMesh();
1461
1462 mDebugInitialized = true;
1463
1464#ifdef SO3_BUILD_DEFERRED
1465 //Create Deffered Manager after resources
1466 try
1467 {
1468 deferredManager = new SDeferredShading();
1469 }
1471 {
1472 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage("[WARNING] Deferred rendering not supported, deactivating it!");
1473 deferredManager = 0;
1474 }
1475#endif
1476
1477 }
1478
1479 mRootInitialised = true;
1480 }
1481 catch(Ogre::Exception &e)
1482 {
1483 MMechostr(MSKDEBUG, ">> Ogre Load error %s\n", e.getDescription().c_str());
1484 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage("An exception has occurred: "+ e.getDescription());
1485 }
1486 }
1487
1488 //update to create ressources
1489 if (dummyWindow)
1490 dummyWindow->update();
1491}
1492
1493bool SRoot::SetFullScreenState(SWindow* window, const bool& state, const int& width, const int& height)
1494{
1495 //disable fullscreen for D3D11
1496 if (renderSystem == SO3_DIRECTX11_RENDERER)
1497 return false;
1498
1499 // cannot set a directX non primary window in fullscreen
1500 if (((renderSystem != SO3_OPENGL_RENDERER) || (renderSystem != SO3_VULKAN_RENDERER) || (renderSystem != SO3_TINY_RENDERER)) && (!window->GetOgreRenderWindowPointer()->isPrimary()))
1501 {
1502 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage("An exception has occurred: Can not set a DirectX window in fullscreen if this this not the first created window.");
1503 return false;
1504 }
1505
1506 //Allow only one window in fullscreen mode
1507 if (state && (fullScreenWindow == 0))
1508 {
1509 try
1510 {
1511 const_cast <Ogre::RenderWindow*> (window->GetOgreRenderWindowPointer())->update();
1512 const_cast <Ogre::RenderWindow*> (window->GetOgreRenderWindowPointer())->setFullscreen(state, width, height);
1513 }
1514 catch (Ogre::Exception &e)
1515 {
1516 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage("An exception has occurred: "+ e.getDescription());
1517 return false;
1518 }
1519
1520 fullScreenWindow = window;
1521 return true;
1522 }
1523 else if (!state && (fullScreenWindow == window))
1524 {
1525 try
1526 {
1527 const_cast <Ogre::RenderWindow*> (fullScreenWindow->GetOgreRenderWindowPointer())->setFullscreen(state, width, height);
1528 const_cast <Ogre::RenderWindow*> (window->GetOgreRenderWindowPointer())->update();
1529 }
1530 catch (Ogre::Exception &e)
1531 {
1532 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage("An exception has occurred: "+ e.getDescription());
1533 return false;
1534 }
1535
1536 fullScreenWindow = 0;
1537 return true;
1538 }
1539
1540 return false;
1541}
1542
1543void SRoot::SetDebugEnable(const bool& enable)
1544{
1545 mDebugEnable = enable;
1546 SSceneMap::iterator iScene = sceneList.begin();
1547 while(iScene != sceneList.end())
1548 {
1549 iScene->second->SetDebugEnable(enable);
1550 iScene++;
1551 }
1552}
1553
1555{
1556 return mDebugEnable;
1557}
1558
1559void SRoot::SetDebugDisplay(const int& color, const int& posx, const int& posy, const int& width, const int& height, const int& charHeight)
1560{
1561 SSceneMap::iterator iScene = sceneList.begin();
1562 while(iScene != sceneList.end())
1563 {
1564 iScene->second->SetDebugDisplay(color, posx, posy, width, height, charHeight);
1565 iScene++;
1566 }
1567}
1568
1569void SRoot::SetDebugText(const std::string& text)
1570{
1571 SSceneMap::iterator iScene = sceneList.begin();
1572 while(iScene != sceneList.end())
1573 {
1574 iScene->second->SetDebugText(text);
1575 iScene++;
1576 }
1577}
1578
1579void SRoot::CreateBoneHelperMesh()
1580{
1581 SBaseMeshsTools::CreateOctahedron("SO3/Bone/Helper/Mesh", .2f, .1f, 1.0f, SO3_INTERNAL_RESOURCE_GROUP);
1582 Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create("SO3/Bone/Helper/Material", SO3_INTERNAL_RESOURCE_GROUP);
1583 material->setReceiveShadows(false);
1584 material->getTechnique(0)->getPass(0)->setLightingEnabled(true);
1585 material->getTechnique(0)->getPass(0)->setAmbient(1, 0, 0);
1586 material->getTechnique(0)->getPass(0)->setDiffuse(1, 0, 0, 1);
1587 material->getTechnique(0)->getPass(0)->setSelfIllumination(1, 0, 0);
1588 material->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false);
1589}
1590
1592{
1593 SSceneMap::iterator iScene = sceneList.begin();
1594 while(iScene != sceneList.end())
1595 {
1596 iScene->second->UpdateCamera(viewport);
1597 iScene++;
1598 }
1599}
1600
1602{
1603 SSceneMap::iterator iScene = sceneList.begin();
1604 while(iScene != sceneList.end())
1605 {
1606 iScene->second->RegisterViewport(viewport);
1607 iScene++;
1608 }
1609}
1610
1612{
1613 SSceneMap::iterator iScene = sceneList.begin();
1614 while(iScene != sceneList.end())
1615 {
1616 iScene->second->UnregisterViewport(viewport);
1617 iScene++;
1618 }
1619}
1620
1621void SRoot::eventOccurred(const Ogre::String &eventName, const Ogre::NameValuePairList *parameters)
1622{
1623 if ((eventName == "DeviceLost") || (eventName == "BeforeDeviceReset"))
1624 {
1625 mDeviceLost = true;
1626 }
1627 else if ((eventName == "DeviceRestored") || (eventName == "AfterDeviceReset"))
1628 {
1629 mDeviceLost = false;
1630 }
1631}
1632
1634{
1635#ifdef _WIN32
1636 return mDeviceLost;
1637#else
1638 return false;
1639#endif
1640}
1641
1643{
1644 if (windowList.empty() || !mResourcesReleased)
1645 return;
1646
1647#ifdef ANDROID
1648 struct android_app* androidApp = (struct android_app*)SCgetExtra("this_inst");
1649 ScolWindowHandle awindow = (ScolWindowHandle)SCgetExtra("hscol");
1650 AConfiguration* config = AConfiguration_new();
1651 if (androidApp)
1652 {
1653 AConfiguration_fromAssetManager(config, androidApp->activity->assetManager);
1654
1655 const SWindowMap lWin = windowList;
1656 SWindowMap::const_iterator iWindowSearched = lWin.begin();
1657 while ((iWindowSearched != lWin.end()))
1658 {
1659 try
1660 {
1661 MMechostr(MSKDEBUG, ">>> ReloadInternalRessources\n");
1662
1663 iWindowSearched->second->SetWindowHandle(awindow);
1664 iWindowSearched->second->GetOgreRenderWindowPointer()->_notifySurfaceCreated(awindow, config);
1665
1666 int nwidth = (int)ANativeWindow_getWidth(awindow);
1667 int nheight = (int)ANativeWindow_getHeight(awindow);
1668
1669 /*int gwidth = nwidth / 2;
1670 int gheight = nheight / 2;
1671
1672 ANativeWindow_setBuffersGeometry((ScolWindowHandle)awindow, gwidth, gheight, 0);*/
1673
1674 iWindowSearched->second->Size(0, 0, nwidth, nheight, 1);
1675 iWindowSearched->second->ResumeWindow();
1676 iWindowSearched->second->SetSizeDirty();
1677 }
1678 catch (Ogre::Exception &e)
1679 {
1680 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage("ReloadInternalRessources : An exception has occurred: " + e.getDescription());
1681 }
1682 iWindowSearched++;
1683 }
1684
1685 SSceneMap sceneList = scolRoot->GetSceneList();
1686 SSceneMap::iterator iScene = sceneList.begin();
1687 while (iScene != sceneList.end())
1688 {
1689 iScene->second->ReloadInternalRessources();
1690 iScene++;
1691 }
1692 }
1693
1694 //SCsetExtra("glContext", eglGetCurrentContext());
1695 //SCsetExtra("glDisplay", eglGetDisplay(EGL_DEFAULT_DISPLAY));
1696 AConfiguration_delete(config);
1697#endif
1698 mResourcesReleased = false;
1699}
1700
1702{
1703 if (mResourcesReleased)
1704 return;
1705
1706 mPaused = true;
1707
1708 //const Ogre::RenderSystemCapabilities* caps = SRoot::getSingletonPtr()->GetOgreRenderSystem()->getCapabilities();
1709 //if (caps && caps->hasCapability(Ogre::RSC_FIXED_FUNCTION) == false)
1710 mShaderGenerator->removeAllShaderBasedTechniques();
1711
1712 if (windowList.empty())
1713 return;
1714
1715 SSceneMap sceneList = scolRoot->GetSceneList();
1716 SSceneMap::iterator iScene = sceneList.begin();
1717 while (iScene != sceneList.end())
1718 {
1719 iScene->second->DestroyInternalRessources();
1720 iScene++;
1721 }
1722
1723 const SWindowMap lWin = windowList;
1724 SWindowMap::const_iterator iWindowSearched = lWin.begin();
1725 while ((iWindowSearched != lWin.end()))
1726 {
1727 MMechostr(MSKDEBUG, ">>> DestroyInternalRessources\n");
1728 try
1729 {
1730 iWindowSearched->second->PauseWindow();
1731#ifdef ANDROID
1732 iWindowSearched->second->GetOgreRenderWindowPointer()->_notifySurfaceDestroyed();
1733 //iWindowSearched->second->SetWindowHandle(0);
1734#endif
1735 }
1736 catch (Ogre::Exception &e)
1737 {
1738 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage("DestroyInternalRessources : An exception has occurred: " + e.getDescription());
1739 }
1740 iWindowSearched++;
1741 }
1742 //SCsetExtra("glContext", 0);
1743 //SCsetExtra("glDisplay", 0);
1744
1745 mResourcesReleased = true;
1746
1747 return;
1748}
1749
1751{
1752 mPaused = true;
1753}
1754
1756{
1757 if (windowList.empty())
1758 return;
1759
1760 const SWindowMap lWin = windowList;
1761 SWindowMap::const_iterator iWindowSearched = lWin.begin();
1762 while ((iWindowSearched != lWin.end()))
1763 {
1764 iWindowSearched->second->SetSizeDirty();
1765 iWindowSearched++;
1766 }
1767
1768 // Clear event times
1769 Ogre::Root::getSingleton().clearEventTimes();
1770
1771 mPaused = false;
1772}
1773
1775{
1776 return mUpdating;
1777}
1778
1780{
1781 return mRendering;
1782}
1783
1785{
1786 if (windowList.empty() || mPaused)
1787 return false;
1788
1789 bool ret = false;
1790
1791 mUpdating = true;
1792#ifdef ANDROID
1793 struct android_app* androidApp = (struct android_app*)SCgetExtra("this_inst");
1794 ScolWindowHandle awindow = (ScolWindowHandle)SCgetExtra("hscol");
1795 if (androidApp == 0 || awindow == 0)
1796 return false;
1797
1798 int aWidth = ANativeWindow_getWidth(awindow);
1799 int aHeight = ANativeWindow_getHeight(awindow);
1800 if (aWidth != mMainWidth || aHeight != mMainHeight)
1801 {
1802 mMainWidth = aWidth;
1803 mMainHeight = aHeight;
1804
1805 SWindow* so3win = SRoot::getSingleton().GetRenderWindow((const ScolWindowHandle&)awindow);
1806 if (so3win != NULL)
1807 {
1808 so3win->Size(0, 0, mMainWidth, mMainHeight, 1);
1809 }
1810 }
1811#endif
1812
1813#ifdef _WIN32
1814# ifndef SO3_USE_DX11
1815 bool valid = true;
1817 {
1818 try
1819 {
1820 Ogre::D3D9Device* device = static_cast<Ogre::D3D9RenderSystem*>(SRoot::getSingleton().GetOgreRenderSystem())->getDeviceManager()->getActiveDevice();
1821 valid = (device != 0) ? !device->isDeviceLost() : false;
1822 }
1823 catch (Ogre::Exception&)
1824 {
1825 valid = false;
1826 }
1827 }
1828
1829 // only update ogre to keep the restore event append when we get the focus to a full screen window
1830 if (mDeviceLost || !valid)
1831 {
1832 const SWindowMap lWin = windowList;
1833 SWindowMap::const_iterator iWindowSearched = lWin.begin();
1834 while ((iWindowSearched != lWin.end()))
1835 {
1836 iWindowSearched->second->Update();
1837 iWindowSearched++;
1838 }
1839
1840 return ret;
1841 }
1842# endif
1843
1844 // manage window resize / screen change
1845 const SWindowMap lWin = windowList;
1846 SWindowMap::const_iterator iWindowSearched = lWin.begin();
1847 while ((iWindowSearched != lWin.end()))
1848 {
1849 /*
1850 POINT screenPoint;
1851 screenPoint.x = 0;
1852 screenPoint.y = 0;
1853 ClientToScreen(iWindowSearched->second->GetWindowHandle(), &screenPoint);
1854 Ogre::Vector2 curPos = iWindowSearched->second->GetScreenPos();
1855
1856 RECT prevScreenRect;
1857 prevScreenRect.left = (int)curPos.x + iWindowSearched->second->GetWidth() / 2;
1858 prevScreenRect.top = (int)curPos.y + iWindowSearched->second->GetHeight() / 2;
1859 prevScreenRect.right = iWindowSearched->second->GetWidth();
1860 prevScreenRect.bottom = iWindowSearched->second->GetHeight();
1861
1862 MONITORINFOEX pminfos;
1863 pminfos.cbSize = sizeof(pminfos);
1864 GetMonitorInfo(MonitorFromRect(&prevScreenRect, MONITOR_DEFAULTTONEAREST), &pminfos);
1865
1866 RECT newScreenRect;
1867 newScreenRect.left = screenPoint.x + iWindowSearched->second->GetWidth() / 2;
1868 newScreenRect.top = screenPoint.y + iWindowSearched->second->GetHeight() / 2;
1869 newScreenRect.right = iWindowSearched->second->GetWidth();
1870 newScreenRect.bottom = iWindowSearched->second->GetHeight();
1871
1872 MONITORINFOEX nminfos;
1873 nminfos.cbSize = sizeof(nminfos);
1874 GetMonitorInfo(MonitorFromRect(&newScreenRect, MONITOR_DEFAULTTONEAREST), &nminfos);
1875
1876 if (Ogre::String(pminfos.szDevice) != Ogre::String(nminfos.szDevice))
1877 {
1878 Ogre::D3D9RenderWindow* rWindow = (Ogre::D3D9RenderWindow*)GetOgreRenderSystem()->getRenderTarget(iWindowSearched->second->GetOgreRenderWindowPointer()->getName());
1879 rWindow->getDevice()->invalidate(rWindow);
1880
1881 // hack to restore the sky
1882 SSceneMap sceneList = scolRoot->GetSceneList();
1883 SSceneMap::iterator iScene = sceneList.begin();
1884 while(iScene != sceneList.end())
1885 {
1886 bool state = iScene->second->GetEnvironment()->GetSkyEnable();
1887 if (state)
1888 {
1889 iScene->second->GetEnvironment()->SetSkyEnable(false);
1890 iScene->second->GetEnvironment()->SetSkyEnable(state);
1891 }
1892
1893 iScene++;
1894 }
1895 }*/
1896
1897 //needed to update selector buffer correctly
1898 iWindowSearched->second->UpdateScreenPos();
1899 if (iWindowSearched->second->GetSizeDirty())
1900 {
1901 iWindowSearched->second->WindowMovedOrResized();
1902 }
1903 iWindowSearched++;
1904 }
1905#else
1906 const SWindowMap lWin = windowList;
1907 SWindowMap::const_iterator iWindowSearched = lWin.begin();
1908 while((iWindowSearched != lWin.end()))
1909 {
1910 #ifdef WIN32
1911 if (iWindowSearched->second->GetOgreRenderWindowPointer()->isActive())
1912 {
1913 if (iWindowSearched->second->GetSizeDirty())
1914 iWindowSearched->second->WindowMovedOrResized();
1915 }
1916 else
1917 {
1918 return false;
1919 }
1920 #else
1921 if (iWindowSearched->second->GetSizeDirty())
1922 {
1923 iWindowSearched->second->WindowMovedOrResized();
1924 }
1925 #endif
1926 iWindowSearched++;
1927 }
1928#endif
1929
1930 // manage OgreWorkQueue
1931 //Ogre::Root::getSingleton().getWorkQueue()->processResponses();
1932
1933 //hack to remove an ogre bug see #http://www.ogre3d.org/mantis/view.php?id=130
1934 //ClearSceneManagerPassMaps();
1935
1936 // Get cef events (events were posted in one of cef's threads, so get those events back to scol's main thread for processing)
1937#if SO3_WEB_NAVIGATOR_BUILD == 1
1938 if(webNavigatorManager != 0)
1939 webNavigatorManager->Update();
1940#endif
1941
1942 // update the scenes
1943 SSceneMap::iterator iScene = sceneList.begin();
1944 while(iScene != sceneList.end())
1945 {
1946 iScene->second->PreUpdate();
1947 iScene++;
1948 }
1949
1950 // Render 3D content
1951 Ogre::Root* ogreRoot = Ogre::Root::getSingletonPtr();
1952 mRendering = true;
1953 try
1954 {
1955 ret = ogreRoot->renderOneFrame();
1956 }
1957 catch (Ogre::Exception &e)
1958 {
1959 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage("An exception has occurred: "+ e.getDescription());
1960 ret = false;
1961 }
1962 mRendering = false;
1963
1964 iScene = sceneList.begin();
1965 while(iScene != sceneList.end())
1966 {
1967 iScene->second->PostUpdate();
1968 iScene++;
1969 }
1970
1971 mUpdating = false;
1972
1973 //clean viewports to del
1974 SWindowMap::const_iterator iWindow = windowList.begin();
1975 while ((iWindow != windowList.end()))
1976 {
1977 iWindow->second->CleanViewports();
1978 iWindow++;
1979 }
1980
1981 return ret;
1982}
1983
1985{
1986#ifdef _WIN32
1987 if(O3Render != 0)
1988 {
1989 if(O3Render->getCapabilities() != 0)
1990 {
1991 if (O3Render->getCapabilities() && O3Render->getCapabilities()->hasCapability(Ogre::RSC_QUAD_BUFFER))
1992 {
1993 Ogre::ConfigOptionMap rendererConfigOptions = O3Render->getConfigOptions();
1994 Ogre::ConfigOptionMap::iterator iQuadBuffer = rendererConfigOptions.find("Stereo Mode");
1995 return ((renderSystem == SO3_OPENGL_RENDERER) && (iQuadBuffer != rendererConfigOptions.end()) && (iQuadBuffer->second.currentValue == "QuadBuffer"));
1996 }
1997 }
1998 }
1999#endif
2000 return false;
2001}
2002
2004{
2005 return quadBufferFocalLength;
2006}
2007
2009{
2010 return quadBufferEyesSeparation;
2011}
2012
2014{
2015 return useVSync;
2016}
2017
2019{
2020 // This var is there to check if the config file values where automatically forced by SO3Engine
2021 bool configForced = false;
2022 bool hasQuadBufferEyeSep = false;
2023 bool hasQuadBufferFocal = false;
2024
2025 // Var for olding values recovered from ini file
2026 RenderSystem iniFileRenderSystem = SRoot::SO3_NONE_RENDER_SYSTEM;
2027 string iniFileFsaa = "";
2028 int iniFileActivateQuadBuffer = 0;
2029
2030 //TODO get the path from scol external
2031#ifdef _WIN32
2032 // execpath
2033 char temporaryPath[MAX_PATH];
2034 GetCurrentDirectory(MAX_PATH, temporaryPath);
2035 std::string execpath(temporaryPath);
2036 boost::algorithm::replace_all(execpath, "\\", "/");
2037
2038 // Subdir install directory path = subpath/subdir
2039 std::string execsubdir;
2040 size_t lastSlash = execpath.find_last_of('/');
2041 if(lastSlash != execpath.npos)
2042 execsubdir = execpath.substr(lastSlash);
2043
2044 // Path to Common App Data directory: commonappdatapath/subdir
2045 string scolUserPath;
2046 HRESULT hr_scolpath = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, temporaryPath);
2047 if(SUCCEEDED(hr_scolpath))
2048 scolUserPath = string(temporaryPath) + execsubdir;
2049
2050#else
2051 std::string execpath((const char*)SCgetExtra("scolExecDir"));
2052 std::string scolUserPath((const char*)SCgetExtra("userFilesDir"));
2053#endif
2054 // Path to first config file
2055 string iniFilePath = scolUserPath + "/usmuser.ini";
2056
2057 // Check that the config file exists
2058 FILE* pFile = fopen(iniFilePath.c_str(), "r");
2059 if(pFile!=NULL)
2060 {
2061 // File founded
2062 fclose (pFile);
2063 }
2064 else
2065 {
2066 // File not found, use the second config file instead
2067#ifndef ANDROID
2068 iniFilePath = execpath + "/usm.ini";
2069#else
2070 iniFilePath = "usm.ini";
2071#endif
2072 }
2073
2074 // Open config file, and parse it.
2075 std::string line;
2076
2077#ifndef ANDROID
2078 std::ifstream iniFile(iniFilePath.c_str());
2079#else
2080 struct android_app* androidApp = (struct android_app*)SCgetExtra("this_inst");
2081 std::stringstream iniFile;
2082 if (androidApp)
2083 {
2084 AAsset* asset = AAssetManager_open(androidApp->activity->assetManager, iniFilePath.c_str(), AASSET_MODE_RANDOM);
2085 if (asset)
2086 {
2087 iniFile.write(reinterpret_cast<const char *>(AAsset_getBuffer(asset)), AAsset_getLength(asset));
2088 AAsset_close(asset);
2089 }
2090 }
2091#endif
2092
2093 if(iniFile)
2094 {
2095 while(std::getline(iniFile, line))
2096 {
2097 // Substract end of line if a comment is detected
2098 size_t firstComment = line.find_first_of('#');
2099 if(firstComment != line.npos)
2100 line = line.substr(0, firstComment);
2101
2102 // Search for SO3Renderer
2103 if(line.find(SO3_CONFIG_RENDERER_KEYWORD) != string::npos)
2104 {
2105#ifdef _WIN32
2106 if((line.find(SO3_CONFIG_RENDERER_DIRECTX) != string::npos)
2107 ||(line.find(SO3_CONFIG_RENDERER_DIRECTX9) != string::npos)
2108 ||(line.find(SO3_CONFIG_RENDERER_DIRECTX11) != string::npos))
2109# ifndef SO3_USE_DX11
2110 iniFileRenderSystem = SRoot::SO3_DIRECTX9_RENDERER;
2111# else
2112 iniFileRenderSystem = SRoot::SO3_DIRECTX11_RENDERER;
2113# endif
2114#endif
2115 if(line.find(SO3_CONFIG_RENDERER_OPENGL) != string::npos)
2116 iniFileRenderSystem = SRoot::SO3_OPENGL_RENDERER;
2117 else if (line.find(SO3_CONFIG_RENDERER_VULKAN) != string::npos)
2118 iniFileRenderSystem = SRoot::SO3_VULKAN_RENDERER;
2119 else if (line.find(SO3_CONFIG_RENDERER_TINY) != string::npos)
2120 iniFileRenderSystem = SRoot::SO3_TINY_RENDERER;
2121 else if (line.find(SO3_CONFIG_RENDERER_METAL) != string::npos)
2122 iniFileRenderSystem = SRoot::SO3_METAL_RENDERER;
2123
2124 }
2125
2126 // Search FSAA
2127 if(line.find(SO3_CONFIG_FSAA_KEYWORD) != string::npos)
2128 {
2129 // Check that a value is present
2130 size_t keywordLength = string(SO3_CONFIG_FSAA_KEYWORD).length() + 1;
2131 if(line.length() > keywordLength)
2132 iniFileFsaa = line.substr(keywordLength);
2133 }
2134
2135 // Search VSYNC
2136 if(line.find(SO3_CONFIG_VSYNC_KEYWORD) != string::npos)
2137 {
2138 // Check that a value is present
2139 size_t keywordLength = string(SO3_CONFIG_VSYNC_KEYWORD).length() + 1;
2140 if(line.length() > keywordLength)
2141 {
2142 string vSyncValue = boost::algorithm::to_lower_copy(line.substr(keywordLength));
2143 if((vSyncValue == "1") || (vSyncValue == "yes") || (vSyncValue == "true") || (vSyncValue == "on"))
2144 useVSync = true;
2145 }
2146 }
2147
2148 // Stereo Quad buffer option enabled?
2149 if(line.find(SO3_CONFIG_QUAD_BUFFER_KEYWORD) != string::npos)
2150 {
2151 // Check that a value is present
2152 size_t keywordLength = string(SO3_CONFIG_QUAD_BUFFER_KEYWORD).length() + 1;
2153 if(line.length() > keywordLength)
2154 {
2155 string quadBufferValue = boost::algorithm::to_lower_copy(line.substr(keywordLength));
2156 if((quadBufferValue == "1") || (quadBufferValue == "yes") || (quadBufferValue == "true") || (quadBufferValue == "on"))
2157 iniFileActivateQuadBuffer = 1;
2158 else
2159 iniFileActivateQuadBuffer = -1;
2160 }
2161 }
2162
2163 // Search stereo focal length
2164 if(line.find(SO3_CONFIG_FOCAL_LENGTH_KEYWORD) != string::npos)
2165 {
2166 // Check that a value is present
2167 size_t keywordLength = string(SO3_CONFIG_FOCAL_LENGTH_KEYWORD).length() + 1;
2168 if(line.length() > keywordLength)
2169 {
2170 std::istringstream is(line.substr(keywordLength));
2171 is >> quadBufferFocalLength;
2172 hasQuadBufferFocal = true;
2173 }
2174 }
2175
2176 // Search stereo eyes separation
2177 if(line.find(SO3_CONFIG_EYES_SEPARATION_KEYWORD) != string::npos)
2178 {
2179 // Check that a value is present
2180 size_t keywordLength = string(SO3_CONFIG_EYES_SEPARATION_KEYWORD).length() + 1;
2181 if(line.length() > keywordLength)
2182 {
2183 std::istringstream is(line.substr(keywordLength));
2184 is >> quadBufferEyesSeparation;
2185 hasQuadBufferEyeSep = true;
2186 }
2187 }
2188 }
2189#ifndef ANDROID
2190 iniFile.close();
2191#endif
2192 }
2193
2194 // If no render system was founded in the ini file, use DirectX as default (for the moment some shaders like fresnel and reflection plans don't work perfectly on openGL).
2195 if(iniFileRenderSystem == SRoot::SO3_NONE_RENDER_SYSTEM)
2196 {
2197 iniFileRenderSystem = SRoot::SO3_OPENGL_RENDERER;
2198 configForced = true;
2199 }
2200
2201#ifdef _WIN32
2202 /*
2203 //todo check creating D3D device
2204 // Checking that the dx version is supported.
2205 if(!scolRoot->CheckDirectxVersion())
2206 {
2207 // No dx, so check if we had already planned to use OpenGL
2208 if(iniFileRenderSystem != SO3_OPENGL_RENDERER)
2209 {
2210 // Force OpenGL
2211 iniFileRenderSystem = SRoot::SO3_OPENGL_RENDERER;
2212 configForced = true;
2213 }
2214 }
2215 */
2216#endif
2217
2218 // Checking quad buffer option
2219 bool wantsQuadBuffer = false;
2220 switch(iniFileActivateQuadBuffer)
2221 {
2222 case 0:
2223 wantsQuadBuffer = false;
2224 configForced = true;
2225 break;
2226 case -1:
2227 wantsQuadBuffer = false;
2228 break;
2229 case 1:
2230 wantsQuadBuffer = true;
2231 break;
2232 }
2233
2234 // Checking focal length
2235 if(!hasQuadBufferEyeSep || !hasQuadBufferFocal)
2236 configForced = true;
2237
2238 // Set fsaa option.
2239 if(iniFileFsaa.empty())
2240 {
2241 iniFileFsaa = "0";
2242 configForced = true;
2243 }
2244 defaultFsaa = iniFileFsaa;
2245
2246 // Set the render system that was detected
2247 if (renderSystem == SO3_NONE_RENDER_SYSTEM) //do only on init
2248 SetRenderSystem(iniFileRenderSystem, wantsQuadBuffer);
2249
2250 // Rewrite ini file with the good values
2251 if(configForced == true)
2252 WriteConfigFile(iniFilePath);
2253}
2254
2255void SRoot::WriteConfigFile(const std::string& filename)
2256{
2257 // Read the existing ini file.
2258 std::stringstream content;
2259 std::ifstream inputIniFile(filename.c_str());
2260
2261 // to avoid usm default value overwritted
2262 bool QuadBufferSetted = false;
2263 if(inputIniFile)
2264 {
2265 std::string line;
2266 while (std::getline(inputIniFile, line))
2267 {
2268 if((line.find(SO3_CONFIG_RENDERER_KEYWORD) == string::npos)
2269 &&(line.find(SO3_CONFIG_FSAA_KEYWORD) == string::npos)
2270 &&(line.find(SO3_CONFIG_FOCAL_LENGTH_KEYWORD) == string::npos)
2271 &&(line.find(SO3_CONFIG_EYES_SEPARATION_KEYWORD) == string::npos))
2272 {
2273 if (line.find(SO3_CONFIG_QUAD_BUFFER_KEYWORD) != string::npos)
2274 QuadBufferSetted = true;
2275
2276 // Rewrite the line as it.
2277 content << line << std::endl;
2278 }
2279 }
2280 inputIniFile.close();
2281
2282 // Add the renderer line in the file
2283 if(renderSystem == SO3_DIRECTX9_RENDERER)
2284 {
2285 content << SO3_CONFIG_RENDERER_KEYWORD << " " << SO3_CONFIG_RENDERER_DIRECTX9 << std::endl;
2286 }
2287 else if(renderSystem == SO3_DIRECTX11_RENDERER)
2288 {
2289 content << SO3_CONFIG_RENDERER_KEYWORD << " " << SO3_CONFIG_RENDERER_DIRECTX11 << std::endl;
2290 }
2291 else if(renderSystem == SO3_OPENGL_RENDERER)
2292 {
2293 content << SO3_CONFIG_RENDERER_KEYWORD << " " << SO3_CONFIG_RENDERER_OPENGL << std::endl;
2294 }
2295 else if (renderSystem == SO3_VULKAN_RENDERER)
2296 {
2297 content << SO3_CONFIG_RENDERER_KEYWORD << " " << SO3_CONFIG_RENDERER_VULKAN << std::endl;
2298 }
2299 else if (renderSystem == SO3_TINY_RENDERER)
2300 {
2301 content << SO3_CONFIG_RENDERER_KEYWORD << " " << SO3_CONFIG_RENDERER_TINY << std::endl;
2302 }
2303 else if (renderSystem == SO3_METAL_RENDERER)
2304 {
2305 content << SO3_CONFIG_RENDERER_KEYWORD << " " << SO3_CONFIG_RENDERER_METAL << std::endl;
2306 }
2307
2308 // Add the FSAA line in the file
2309 content << SO3_CONFIG_FSAA_KEYWORD << " " << defaultFsaa << std::endl;
2310
2311 // In case the QuadBuffer line was not found in the file
2312 if(O3Render != 0 && !QuadBufferSetted)
2313 {
2315 {
2316 // Quad buffer enable
2317 content << SO3_CONFIG_QUAD_BUFFER_KEYWORD << " yes" << std::endl;
2318 }
2319 else
2320 {
2321 // No quad buffer stereo support with this renderer, or quad buffer disabled.
2322 content << SO3_CONFIG_QUAD_BUFFER_KEYWORD << " no" << std::endl;
2323 }
2324 }
2325
2326 // Store quad buffer focal length
2327 content << SO3_CONFIG_FOCAL_LENGTH_KEYWORD << " " << quadBufferFocalLength << std::endl;
2328
2329 // Store quad buffer eyes separation distance
2330 content << SO3_CONFIG_EYES_SEPARATION_KEYWORD << " " << quadBufferEyesSeparation << std::endl;
2331
2332 // Write content to file
2333 std::ofstream outputIniFile(filename.c_str(), std::ios::out | std::ios::trunc);
2334 if(outputIniFile)
2335 {
2336 outputIniFile << content.str();
2337 outputIniFile.close();
2338 }
2339 }
2340}
2341
2342
2343void SRoot::RemoveGeneratedMaterial(Ogre::Material* mat)
2344{
2345 if (mat)
2346 mShaderGenerator->removeAllShaderBasedTechniques(mat->getName(), mat->getGroup());
2347}
2348
2349
2350void SRoot::InvalidateGeneratedMaterial(Ogre::Material* mat)
2351{
2352 if (mat)
2353 mShaderGenerator->invalidateMaterial(Ogre::MSN_SHADERGEN, mat->getName(), mat->getGroup());
2354}
2355
2356
2357//Shader Generator
2358Ogre::Technique* ShaderGeneratorTechniqueResolverListener::handleSchemeNotFound(unsigned short schemeIndex, const Ogre::String& schemeName, Ogre::Material* originalMaterial, unsigned short lodIndex, const Ogre::Renderable* rend)
2359{
2360 Ogre::RTShader::ShaderGenerator* mGenerator = Ogre::RTShader::ShaderGenerator::getSingletonPtr();
2361
2362 std::string cSchemeName = schemeName;
2363 if (cSchemeName != Ogre::MSN_SHADERGEN)
2364 cSchemeName = cSchemeName.erase(0, 15);
2365
2366 //Check material for compatible scheme
2367 Ogre::Technique* tech = 0;
2368
2369 //look for convertible technique
2370 Ogre::Material::Techniques techList = originalMaterial->getTechniques();
2371 for (unsigned int i = 0; i < techList.size(); i++)
2372 {
2373 Ogre::Technique* curTechnique = techList[i];
2374 Ogre::String curScheme = curTechnique->getSchemeName();
2375 Ogre::Any bindedSTechnique = curTechnique->getUserObjectBindings().getUserAny("STechnique");
2376 if (bindedSTechnique.has_value())
2377 {
2378 STechnique* so3Technique = Ogre::any_cast<STechnique*> (bindedSTechnique);
2379 curScheme = so3Technique->GetOriginalScheme();
2380 }
2381
2382 if (curScheme == cSchemeName)
2383 {
2384 //reset scheme to original name
2385 curTechnique->setSchemeName(curScheme);
2386 tech = curTechnique;
2387 break;
2388 }
2389 }
2390
2391 // if we have a technique for this scheme this means it's not compatible so we will try to convert it
2392 // otherwise we get the first compatible technique if we have one
2393 if (!tech)
2394 {
2395 Ogre::Material::Techniques techList = originalMaterial->getSupportedTechniques();
2396 tech = (techList.size() > 0) ? techList[0] : 0;
2397 }
2398
2399 //check for compatible pass first
2400 if (tech)
2401 {
2402 int nbGoodPass = 0;
2403 Ogre::Technique::Passes passList = tech->getPasses();
2404 for (unsigned short i = 0; i < passList.size(); i++)
2405 {
2406 Ogre::Pass* pass = passList[i];
2407 Ogre::Any bindedSPass = pass->getUserObjectBindings().getUserAny("SPass");
2408 bool isGenerated = false;
2409 if (bindedSPass.has_value())
2410 {
2411 SPass* matPass = Ogre::any_cast<SPass*> (bindedSPass);
2412 isGenerated = matPass->IsShaderGenerated();
2413 }
2414
2415 if (pass->hasVertexProgram() && pass->hasFragmentProgram() && !isGenerated)
2416 {
2417 Ogre::GpuProgramPtr vp = pass->getVertexProgram();
2418 Ogre::GpuProgramPtr fp = pass->getFragmentProgram();
2419 if (vp && fp && vp->isSupported() && fp->isSupported())
2420 {
2421 nbGoodPass++;
2422 }
2423 }
2424 }
2425 if (nbGoodPass == tech->getNumPasses())
2426 {
2427 tech->setSchemeName(schemeName);
2428 //force loading to skip this the next time
2429 originalMaterial->compile();
2430 return tech;
2431 }
2432 }
2433
2434 //look for first convertible technique if there is no compatible or corresponding technique
2435 if (!tech)
2436 {
2437 techList = originalMaterial->getTechniques();
2438 for (unsigned int i = 0; i < techList.size(); i++)
2439 {
2440 Ogre::Technique* curTechnique = techList[i];
2441 if ((curTechnique->getSchemeName() == Ogre::MSN_DEFAULT) || (curTechnique->getSchemeName() == "basic_mat") || (curTechnique->getSchemeName() == "SO3_LEGACY"))
2442 {
2443 tech = curTechnique;
2444 break;
2445 }
2446 }
2447 }
2448
2449 if (tech)
2450 {
2451 //search pass
2452 Ogre::Technique::Passes passList = tech->getPasses();
2453 for (unsigned short i = 0; i < passList.size(); i++)
2454 {
2455 Ogre::Pass* ambpass = 0;
2456 Ogre::Pass* pass = passList[i];
2457
2458 bool isShadowPass = false;
2460 SSceneMap::iterator iScene = sceneList.begin();
2461 while (iScene != sceneList.end())
2462 {
2463 if (iScene->second->GetShadowManager() && iScene->second->GetShadowManager()->IsShadowMaterialPass(pass))
2464 isShadowPass = true;
2465
2466 iScene++;
2467 }
2468
2469 if (isShadowPass)
2470 continue;
2471
2472 if (pass && (pass->getIlluminationStage() == Ogre::IS_AMBIENT))
2473 {
2474 ambpass = pass;
2475 }
2476 else if (pass && (pass->getIlluminationStage() == Ogre::IS_PER_LIGHT || pass->getIteratePerLight()))
2477 {
2478 if (ambpass)
2479 {
2480 ambpass->setAmbient(pass->getAmbient());
2481 ambpass->setDiffuse(pass->getDiffuse());
2482 ambpass->setEmissive(pass->getEmissive());
2483 ambpass->setSpecular(pass->getSpecular());
2484 ambpass->setShininess(pass->getShininess());
2485
2486 size_t nbTex = pass->getNumTextureUnitStates();
2487 for (size_t t = 0; t < nbTex; t++)
2488 {
2489 Ogre::TextureUnitState* ustate = pass->getTextureUnitState(t);
2490 ambpass->addTextureUnitState(ustate);
2491 }
2492
2493 ambpass->setVertexProgram("", true);
2494 ambpass->setFragmentProgram("", true);
2495
2496 ambpass->setIlluminationStage(Ogre::IS_UNKNOWN);
2497 tech->removePass(i);
2498 }
2499 else
2500 {
2501 pass->setIlluminationStage(Ogre::IS_UNKNOWN);
2502 pass->setDepthWriteEnabled(true);
2503 pass->setDepthCheckEnabled(true);
2504 pass->setVertexProgram("", true);
2505 pass->setFragmentProgram("", true);
2506 pass->setMaxSimultaneousLights(3);
2507 pass->setIteratePerLight(false);
2508 }
2509
2510 //originalMaterial->reload();
2511 }
2512 }
2513 }
2514
2515 //remove shader on technique
2516 //if (tech->getSchemeName() == "SO3_LEGACY")
2517 //{
2518 // Ogre::Any bindedSTechnique = tech->getUserObjectBindings().getUserAny("STechnique");
2519 // if (bindedSTechnique.has_value())
2520 // {
2521 // STechnique* so3Technique = Ogre::any_cast<STechnique*> (bindedSTechnique);
2522 // int np = so3Technique->GetNumPasses();
2523 // for (int p = 0; p < np; p++)
2524 // {
2525 // SPass* cpass = so3Technique->GetPass(p);
2526 // if (cpass)
2527 // cpass->CleanGeneratedShader();
2528 // }
2529 // }
2530 //}
2531
2532 // Create shader generated technique for this material.
2533 bool techniqueCreated = mGenerator->createShaderBasedTechnique(
2534 *originalMaterial,
2535 tech->getSchemeName(), //Ogre::MSN_DEFAULT,
2536 schemeName, true);
2537
2538 if (!techniqueCreated)
2539 {
2540 //try again with basic mat
2541 techniqueCreated = mGenerator->createShaderBasedTechnique(
2542 *originalMaterial,
2543 "basic_mat",
2544 schemeName, false);
2545
2546 if (!techniqueCreated)
2547 {
2548 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage("Material scheme conversion failed from " + tech->getSchemeName() + " to " + schemeName + " on material : " + originalMaterial->getName());
2549 return NULL;
2550 }
2551 }
2552
2553 // add RTSS params
2554 Ogre::Technique::Passes passList = tech->getPasses();
2555 for (unsigned short i = 0; i < passList.size(); i++)
2556 {
2557 Ogre::Pass* pass = passList[i];
2558 bool ignoreSlicePlane = true;
2559
2560 Ogre::Any bindedSTechnique = tech->getUserObjectBindings().getUserAny("STechnique");
2561 if (bindedSTechnique.has_value())
2562 {
2563 STechnique* so3Technique = Ogre::any_cast<STechnique*> (bindedSTechnique);
2564 ignoreSlicePlane = so3Technique->GetParentMaterial()->GetIgnoreSlicePlane();
2565 }
2566 SShaderGenerator shaderRTSS(tech, pass, SShaderGenerator::ShaderGeneratorRTSS, ignoreSlicePlane || !SRoot::getSingletonPtr()->GetSlicePlaneState());
2567 shaderRTSS.ApplyShader();
2568 }
2569
2570 // Case technique registration succeeded.
2571 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage("Material scheme converted from " + tech->getSchemeName() + " to " + schemeName + " on material : " + originalMaterial->getName() + " with group : " + originalMaterial->getGroup());
2572
2573 // Force creating the shaders for the generated technique.
2574 try
2575 {
2576 mGenerator->validateMaterial(schemeName, originalMaterial->getName(), originalMaterial->getGroup());
2577 }
2578 catch (Ogre::Exception &)
2579 {
2580 return Ogre::MaterialManager::getSingletonPtr()->getByName("BaseWhite", Ogre::RGN_INTERNAL)->getBestTechnique();
2581 }
2582
2583 if (originalMaterial->getLoadingState() == Ogre::Resource::LOADSTATE_UNLOADED)
2584 originalMaterial->compile();
2585
2586 //rebuild default shaders
2587 //if (tech->getSchemeName() == "SO3_LEGACY")
2588 //{
2589 // Ogre::Any bindedSTechnique = tech->getUserObjectBindings().getUserAny("STechnique");
2590 // if (bindedSTechnique.has_value())
2591 // {
2592 // STechnique* so3Technique = Ogre::any_cast<STechnique*> (bindedSTechnique);
2593 // int np = so3Technique->GetNumPasses();
2594 // for (int p = 0; p < np; p++)
2595 // {
2596 // SPass* cpass = so3Technique->GetPass(p);
2597 // if (cpass)
2598 // cpass->BuildShader(true);
2599 // }
2600 // }
2601 //}
2602
2603 // Grab the generated technique.
2604 techList = originalMaterial->getTechniques();
2605 for(unsigned int i = 0; i < techList.size(); i++)
2606 {
2607 Ogre::Technique* curTech = techList[i];
2608 MMechostr(MSKDEBUG, ">>>> Material %s technique scheme name : %s > %s\n", originalMaterial->getName().c_str(), schemeName.c_str(), curTech->getSchemeName().c_str());
2609 if (curTech->getSchemeName() == schemeName)
2610 {
2611 //generate shadow pass warning on multiple scene ?!
2612 /*
2613 SSceneMap sceneList = SRoot::getSingleton().GetSceneList();
2614 SSceneMap::iterator iScene = sceneList.begin();
2615 while (iScene != sceneList.end())
2616 {
2617 if (iScene->second->GetShadowManager())
2618 iScene->second->GetShadowManager()->UpdateShadowMaterial(curTech);
2619
2620 iScene++;
2621 }
2622 */
2623 return curTech;
2624 }
2625 }
2626 return NULL;
2627}
2628
2630{
2631 Ogre::RTShader::ShaderGenerator* mGenerator = Ogre::RTShader::ShaderGenerator::getSingletonPtr();
2632 if (mGenerator->hasRenderState(tech->getSchemeName()))
2633 {
2634 Ogre::Material* mat = tech->getParent();
2635 mGenerator->validateMaterialIlluminationPasses(tech->getSchemeName(), mat->getName(), mat->getGroup());
2636 return true;
2637 }
2638 return false;
2639}
2640
2642{
2643 Ogre::RTShader::ShaderGenerator* mGenerator = Ogre::RTShader::ShaderGenerator::getSingletonPtr();
2644 if (mGenerator->hasRenderState(tech->getSchemeName()))
2645 {
2646 Ogre::Material* mat = tech->getParent();
2647 mGenerator->invalidateMaterialIlluminationPasses(tech->getSchemeName(), mat->getName(), mat->getGroup());
2648 return true;
2649 }
2650 return false;
2651}
2652
2653bool SRoot::initialiseRTShaderSystem()
2654{
2655 if (Ogre::RTShader::ShaderGenerator::initialize())
2656 {
2657 mShaderGenerator = Ogre::RTShader::ShaderGenerator::getSingletonPtr();
2658
2659 Ogre::RTShader::SubRenderStateFactory* curFactory = OGRE_NEW FFPClipPLaneFactory;
2660 mShaderGenerator->addSubRenderStateFactory(curFactory);
2661
2662 curFactory = OGRE_NEW AdvancedCookTorranceLightingFactory;
2663 mShaderGenerator->addSubRenderStateFactory(curFactory);
2664
2665 // Create and register the material manager listener if it doesn't exist yet.
2666 if (mMaterialMgrListener == NULL)
2667 {
2668 mMaterialMgrListener = new ShaderGeneratorTechniqueResolverListener();
2669 Ogre::MaterialManager::getSingleton().addListener(mMaterialMgrListener);
2670 }
2671
2672 // create a dummy scene before parsing resources for RTSS
2673 mDummyScene = O3Root->createSceneManager(Ogre::SMT_DEFAULT, "DummyScene");
2674 Ogre::AxisAlignedBox octreeBox(-1, -1, -1, 1, 1, 1);
2675 int octreeDepth = 0;
2676 mDummyScene->setOption("Size", &octreeBox);
2677 mDummyScene->setOption("Depth", &octreeDepth);
2678
2679 Ogre::RenderQueue* rq = mDummyScene->getRenderQueue();
2680 rq->getQueueGroup(Ogre::RENDER_QUEUE_WORLD_GEOMETRY_1)->setShadowsEnabled(false);
2681 rq->getQueueGroup(Ogre::RENDER_QUEUE_WORLD_GEOMETRY_2)->setShadowsEnabled(false);
2682 rq->getQueueGroup(Ogre::RENDER_QUEUE_MAIN)->setShadowsEnabled(false);
2683
2684 mShaderGenerator->addSceneManager(mDummyScene);
2685
2686 auto mainRenderState = mShaderGenerator->getRenderState(Ogre::MSN_SHADERGEN);
2687 // reset global light state
2688 mainRenderState->setLightCount(0);
2689 mainRenderState->setLightCountAutoUpdate(true);
2690 mainRenderState->resetToBuiltinSubRenderStates();
2691
2692 auto perPixelLightModel = mShaderGenerator->createSubRenderState(Ogre::RTShader::SRS_PER_VERTEX_LIGHTING);
2693 mainRenderState->addTemplateSubRenderState(perPixelLightModel);
2694
2695 mShaderGenerator->invalidateScheme(Ogre::MSN_SHADERGEN);
2696 }
2697
2698 return true;
2699}
2700
2701/*-----------------------------------------------------------------------------
2702| Destroy the RT Shader system.
2703-----------------------------------------------------------------------------*/
2704void SRoot::destroyRTShaderSystem()
2705{
2706 // Restore default scheme.
2707 Ogre::MaterialManager::getSingleton().setActiveScheme(Ogre::MSN_DEFAULT);
2708
2709 if (mDummyScene)
2710 {
2711 mShaderGenerator->removeSceneManager(mDummyScene);
2712 O3Root->destroySceneManager(mDummyScene);
2713 mDummyScene = 0;
2714 }
2715
2716 // Unregister the material manager listener.
2717 if (mMaterialMgrListener != NULL)
2718 {
2719 Ogre::MaterialManager::getSingleton().removeListener(mMaterialMgrListener);
2720 delete mMaterialMgrListener;
2721 mMaterialMgrListener = NULL;
2722 }
2723
2724 if (mShaderGenerator)
2725 {
2726 mShaderGenerator->destroy();
2727 mShaderGenerator = 0;
2728 }
2729}
2730
2734{
2735 if (!mSlicePlaneParams || (mSlicePlaneState == state))
2736 return;
2737
2738 mSlicePlaneState = state;
2739
2740 if (mSlicePlaneState)
2741 mSlicePlaneParams->setNamedConstant("slicePlane", mSlicePlane);
2742 else
2743 mSlicePlaneParams->setNamedConstant("slicePlane", Ogre::Vector4::ZERO);
2744
2745 Ogre::ResourceManager::ResourceMapIterator it = Ogre::MaterialManager::getSingleton().getResourceIterator();
2746 while (it.hasMoreElements())
2747 {
2748 Ogre::MaterialPtr mat = Ogre::static_pointer_cast<Ogre::Material>(it.getNext());
2749 RemoveGeneratedMaterial(mat.get());
2750
2751 Ogre::Material::Techniques techs = mat->getTechniques();
2752 for (unsigned int i = 0; i < techs.size(); i++)
2753 {
2754 Ogre::Technique* tech = techs[i];
2755
2756 //skip generated techniques like SSAO
2757 if (tech->getSchemeName().find(std::string(SO3_INTERNAL_RESOURCE_GROUP)) != Ogre::String::npos || tech->getResourceGroup().find(std::string(SO3_INTERNAL_RESOURCE_GROUP)) != Ogre::String::npos)
2758 continue;
2759
2760 if (((tech->getSchemeName() != Ogre::MSN_SHADERGEN) &&
2761 (tech->getSchemeName() != "SO3_LEGACY") &&
2762 (tech->getSchemeName() != "Default") &&
2763 (tech->getSchemeName() != "basic_mat")))
2764 continue;
2765
2766 Ogre::Any bindedSTechnique = tech->getUserObjectBindings().getUserAny("STechnique");
2767 if (!bindedSTechnique.has_value())
2768 continue;
2769
2770 STechnique* stechnique = Ogre::any_cast<STechnique*> (bindedSTechnique);
2771 if (!stechnique)
2772 continue;
2773
2774 if (stechnique->GetParentMaterial()->GetIgnoreSlicePlane())
2775 continue;
2776
2777 tech->setSchemeName(stechnique->GetOriginalScheme());
2778 stechnique->UpdateGeneratedTech(true);
2779 }
2780 }
2781}
2782
2785void SRoot::SetSlicePlane(Ogre::Vector4 plane)
2786{
2787 mSlicePlane = plane;
2788
2789 if (!mSlicePlaneParams || !mSlicePlaneState)
2790 return;
2791
2792 mSlicePlaneParams->setNamedConstant("slicePlane", mSlicePlane);
2793}
2794
2798{
2799 return mSlicePlaneState;
2800}
2801
2805{
2806 return mSlicePlane;
2807}
2808
2809
2810void SRoot::SetProgramCameraParameter(float fov, float znear, float zfar, float focalLength)
2811{
2812 const Ogre::RenderSystem *renderSystem = SRoot::getSingleton().GetOgreRenderSystem();
2813 float prjA = 0.0;
2814 float prjB = 0.0;
2815 if (!renderSystem->isReverseDepthBufferEnabled())
2816 {
2817 prjA = zfar / (zfar - znear); // projectionA
2818 prjB = (-zfar * znear) / (zfar - znear); // projectionB
2819 }
2820 else
2821 {
2822 prjA = -znear / (zfar - znear); // projectionA
2823 prjB = (zfar * znear) / (zfar - znear); // projectionB
2824 }
2825 prjB /= zfar;
2826
2827 mCommonParams->setNamedConstant("cameraProjection", Ogre::Vector4(prjA, prjB, 0.0, 0.0));
2828 mCommonParams->setNamedConstant("cameraParams", Ogre::Vector4(znear, zfar, focalLength, fov));
2829}
2830
2831}
int SO3_LOGS_MSG
Definition SCOLLog.cpp:44
void(* SetRenderDeviceGetFunction)(std::function< void *()> fptr)
Definition SO3Root.cpp:92
SWindow * so3win
Definition SO3SCOL.cpp:5116
MMechostr(MSKDEBUG, " > Start loading Plugin SO3Engine dll\n")
int nheight
Definition SO3SCOL.cpp:5095
std::string firstPartition(((packdir) SCgetExtra("FirstPack")) ->path)
ScolWindowHandle win
Definition SO3SCOL.cpp:5092
int nwidth
Definition SO3SCOL.cpp:5094
SRoot * scolRoot
Shared data.
Definition SO3SCOL.cpp:186
static CSMGpuConstants & getSingleton()
static CSMGpuConstants * getSingletonPtr()
static Ogre::MeshPtr CreateOctahedron(const Ogre::String &strName, float baseLength, float bottomDistance, float upDistance, Ogre::String groupName=Ogre::RGN_DEFAULT)
std::string GetName() const
SException indicating that a call to an unimplemented functionnality was done.
static void Reset()
bool GetIgnoreSlicePlane()
bool IsShaderGenerated()
Definition SO3Pass.cpp:151
bool GetRttPixelFormat(Ogre::PixelFormat &format, bool alpha=false, bool floattex=false)
Definition SO3Root.cpp:650
bool IsRendering()
Definition SO3Root.cpp:1779
void UnregisterViewport(SViewPort *viewport)
Definition SO3Root.cpp:1611
SScene * GetScene(const std::string &sceneName)
Definition SO3Root.cpp:551
void SetLogEnable(const bool &state)
Definition SO3Root.cpp:374
SDeferredShading * GetDeferredManager()
Definition SO3Root.cpp:312
void DestroyInternalRessources()
Definition SO3Root.cpp:1701
RenderSystem GetRenderSystem()
Definition SO3Root.cpp:860
void RemoveScene(SScene *existingScene)
Definition SO3Root.cpp:585
const SWindowMap & GetRenderWindowList() const
Definition SO3Root.cpp:821
bool Update()
Definition SO3Root.cpp:1784
bool IsRenderInitialised()
Definition SO3Root.cpp:306
void AddRenderWindow(SWindow *existingWindow)
Definition SO3Root.cpp:826
bool GetQuadBufferEnable()
Definition SO3Root.cpp:1984
SWindow * CreateRenderWindow(const ScolWindowHandle windowHandle, const std::string &windowName, const int &width, const int &height, const std::string &renderWindowFsaa="default")
Definition SO3Root.cpp:768
void SetLogMask(const Ogre::LogMessageLevel &level)
Definition SO3Root.cpp:384
bool SetFullScreenState(SWindow *window, const bool &state, const int &width, const int &height)
Definition SO3Root.cpp:1493
void AddLogListener(SLogListener *newLogListener)
Definition SO3Root.cpp:358
SWindow * GetRenderWindow(const std::string &windowName)
Definition SO3Root.cpp:812
void RegisterViewport(SViewPort *viewport)
Definition SO3Root.cpp:1601
Ogre::Root * GetOgreRootPointer()
Definition SO3Root.cpp:301
void RemoveLogListener(SLogListener *existingLogListener)
Definition SO3Root.cpp:366
void InitRenderer(SWindow *pwin=0)
Definition SO3Root.cpp:1310
void RemoveManualRessourceGroup(std::string name)
Definition SO3Root.cpp:620
bool checkFSAA(const Ogre::String &val)
Definition SO3Root.cpp:389
SScene * CreateScene(const std::string &newSceneName)
Definition SO3Root.cpp:535
void DeleteScene(SScene *existingScene)
Definition SO3Root.cpp:542
@ SO3_NONE_RENDER_SYSTEM
Definition SO3Root.h:77
@ SO3_DIRECTX9_RENDERER
Definition SO3Root.h:78
@ SO3_METAL_RENDERER
Definition SO3Root.h:83
@ SO3_DIRECTX11_RENDERER
Definition SO3Root.h:79
@ SO3_TINY_RENDERER
Definition SO3Root.h:84
@ SO3_OPENGL_RENDERER
Definition SO3Root.h:80
@ SO3_VULKAN_RENDERER
Definition SO3Root.h:82
void SetDebugDisplay(const int &color, const int &posx, const int &posy, const int &width, const int &height, const int &charHeight)
Definition SO3Root.cpp:1559
void SetProgramCameraParameter(float fov, float znear, float zfar, float focalLength)
Definition SO3Root.cpp:2810
void UpdateCamera(SViewPort *viewport)
Definition SO3Root.cpp:1591
void DeleteRenderWindow(SWindow *existingWindow)
Definition SO3Root.cpp:787
bool GetVSyncEnable()
Definition SO3Root.cpp:2013
bool isDeviceLost()
Definition SO3Root.cpp:1633
void AddManualRessourceGroup(std::string name)
Definition SO3Root.cpp:607
std::vector< std::string > GetMultisamplingMode(const RenderSystem &wishedRenderSystem)
Definition SO3Root.cpp:992
bool GetSlicePlaneState()
Definition SO3Root.cpp:2797
const SSceneMap & GetSceneList() const
Definition SO3Root.cpp:560
bool GetLogEnable()
Definition SO3Root.cpp:379
void SetSlicePlane(Ogre::Vector4 plane)
Definition SO3Root.cpp:2785
void ReloadInternalRessources()
Definition SO3Root.cpp:1642
Ogre::RenderSystem * GetOgreRenderSystem()
Definition SO3Root.cpp:865
virtual void eventOccurred(const Ogre::String &eventName, const Ogre::NameValuePairList *parameters)
Definition SO3Root.cpp:1621
float GetQuadBufferFocalLength()
Definition SO3Root.cpp:2003
void AddScene(SScene *existingScene)
Definition SO3Root.cpp:565
void SetSlicePlaneState(bool state)
Definition SO3Root.cpp:2733
void SetDebugEnable(const bool &enable)
Definition SO3Root.cpp:1543
void Resume()
Definition SO3Root.cpp:1755
bool IsUpdating()
Definition SO3Root.cpp:1774
void RemoveGeneratedMaterial(Ogre::Material *mat)
Definition SO3Root.cpp:2343
void SetDebugText(const std::string &text)
Definition SO3Root.cpp:1569
static SRoot & getSingleton()
Definition SO3Root.cpp:116
static SRoot * getSingletonPtr()
Definition SO3Root.cpp:111
virtual void messageLogged(const Ogre::String &message, Ogre::LogMessageLevel lml, bool maskDebug, const Ogre::String &logName, bool &skipMessage)
Definition SO3Root.cpp:334
void * GetD3Ddevice()
Definition SO3Root.cpp:290
bool GetDebugEnable()
Definition SO3Root.cpp:1554
void ParseConfigFile()
Definition SO3Root.cpp:2018
Ogre::Vector4 GetSlicePlane()
Definition SO3Root.cpp:2804
void InvalidateGeneratedMaterial(Ogre::Material *mat)
Definition SO3Root.cpp:2350
void Pause()
Definition SO3Root.cpp:1750
void ClearManualRessourceGroups()
Definition SO3Root.cpp:633
bool CheckDirectxVersion()
Definition SO3Root.cpp:1066
void RemoveRenderWindow(SWindow *existingWindow)
Definition SO3Root.cpp:841
float GetQuadBufferEyesSeparation()
Definition SO3Root.cpp:2008
void SetDebugEnable(const bool &enable)
Ogre::SceneManager * GetOgreScenePointer()
Definition SO3Scene.cpp:449
static void Reset()
void UpdateGeneratedTech(bool full=false)
SMaterial * GetParentMaterial()
const Ogre::String GetOriginalScheme()
void AddWidgetFactory(SWidgetFactory *newWidgetFactory)
Ogre::RenderWindow * GetOgreRenderWindowPointer()
int Size(const int &x, const int &y, const int &w, const int &h, const int &ext)
virtual bool afterIlluminationPassesCreated(Ogre::Technique *tech)
Definition SO3Root.cpp:2629
virtual bool beforeIlluminationPassesCleared(Ogre::Technique *tech)
Definition SO3Root.cpp:2641
virtual Ogre::Technique * handleSchemeNotFound(unsigned short schemeIndex, const Ogre::String &schemeName, Ogre::Material *originalMaterial, unsigned short lodIndex, const Ogre::Renderable *rend)
Definition SO3Root.cpp:2358
std::unordered_map< std::string, SScene * > SSceneMap
std::unordered_map< std::string, SWindow * > SWindowMap