1 /*! 2 @file 3 @author Albert Semenov 4 @date 04/2008 5 */ 6 7 #include "MyGUI_OgreDataManager.h" 8 #include "MyGUI_OgreRenderManager.h" 9 #include "MyGUI_OgreTexture.h" 10 #include "MyGUI_OgreVertexBuffer.h" 11 #include "MyGUI_LogManager.h" 12 #include "MyGUI_OgreDiagnostic.h" 13 #include "MyGUI_Timer.h" 14 #include "MyGUI_Gui.h" 15 16 namespace MyGUI 17 { 18 getInstance()19 OgreRenderManager& OgreRenderManager::getInstance() 20 { 21 return *getInstancePtr(); 22 } getInstancePtr()23 OgreRenderManager* OgreRenderManager::getInstancePtr() 24 { 25 return static_cast<OgreRenderManager*>(RenderManager::getInstancePtr()); 26 } 27 OgreRenderManager()28 OgreRenderManager::OgreRenderManager() : 29 mUpdate(false), 30 mSceneManager(nullptr), 31 mWindow(nullptr), 32 mActiveViewport(0), 33 mRenderSystem(nullptr), 34 mIsInitialise(false), 35 mManualRender(false), 36 mCountBatch(0) 37 { 38 } 39 initialise(Ogre::RenderWindow * _window,Ogre::SceneManager * _scene)40 void OgreRenderManager::initialise(Ogre::RenderWindow* _window, Ogre::SceneManager* _scene) 41 { 42 MYGUI_PLATFORM_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice"); 43 MYGUI_PLATFORM_LOG(Info, "* Initialise: " << getClassTypeName()); 44 45 mColorBlendMode.blendType = Ogre::LBT_COLOUR; 46 mColorBlendMode.source1 = Ogre::LBS_TEXTURE; 47 mColorBlendMode.source2 = Ogre::LBS_DIFFUSE; 48 mColorBlendMode.operation = Ogre::LBX_MODULATE; 49 50 mAlphaBlendMode.blendType = Ogre::LBT_ALPHA; 51 mAlphaBlendMode.source1 = Ogre::LBS_TEXTURE; 52 mAlphaBlendMode.source2 = Ogre::LBS_DIFFUSE; 53 mAlphaBlendMode.operation = Ogre::LBX_MODULATE; 54 55 mTextureAddressMode.u = Ogre::TextureUnitState::TAM_CLAMP; 56 mTextureAddressMode.v = Ogre::TextureUnitState::TAM_CLAMP; 57 mTextureAddressMode.w = Ogre::TextureUnitState::TAM_CLAMP; 58 59 mSceneManager = nullptr; 60 mWindow = nullptr; 61 mUpdate = false; 62 mRenderSystem = nullptr; 63 mActiveViewport = 0; 64 65 Ogre::Root* root = Ogre::Root::getSingletonPtr(); 66 if (root != nullptr) 67 setRenderSystem(root->getRenderSystem()); 68 setRenderWindow(_window); 69 setSceneManager(_scene); 70 71 MYGUI_PLATFORM_LOG(Info, getClassTypeName() << " successfully initialized"); 72 mIsInitialise = true; 73 } 74 shutdown()75 void OgreRenderManager::shutdown() 76 { 77 MYGUI_PLATFORM_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised"); 78 MYGUI_PLATFORM_LOG(Info, "* Shutdown: " << getClassTypeName()); 79 80 destroyAllResources(); 81 82 setSceneManager(nullptr); 83 setRenderWindow(nullptr); 84 setRenderSystem(nullptr); 85 86 MYGUI_PLATFORM_LOG(Info, getClassTypeName() << " successfully shutdown"); 87 mIsInitialise = false; 88 } 89 setRenderSystem(Ogre::RenderSystem * _render)90 void OgreRenderManager::setRenderSystem(Ogre::RenderSystem* _render) 91 { 92 // отписываемся 93 if (mRenderSystem != nullptr) 94 { 95 mRenderSystem->removeListener(this); 96 mRenderSystem = nullptr; 97 } 98 99 mRenderSystem = _render; 100 101 // подписываемся на рендер евент 102 if (mRenderSystem != nullptr) 103 { 104 mRenderSystem->addListener(this); 105 106 // формат цвета в вершинах 107 Ogre::VertexElementType vertex_type = mRenderSystem->getColourVertexElementType(); 108 if (vertex_type == Ogre::VET_COLOUR_ARGB) 109 mVertexFormat = VertexColourType::ColourARGB; 110 else if (vertex_type == Ogre::VET_COLOUR_ABGR) 111 mVertexFormat = VertexColourType::ColourABGR; 112 113 updateRenderInfo(); 114 115 if (!mRenderSystem->getCapabilities()->hasCapability(Ogre::RSC_FIXED_FUNCTION)) 116 { 117 std::string shaderLanguage; 118 if (Ogre::HighLevelGpuProgramManager::getSingleton().isLanguageSupported("glsl")) 119 shaderLanguage = "glsl"; 120 else if (Ogre::HighLevelGpuProgramManager::getSingleton().isLanguageSupported("glsles")) 121 shaderLanguage = "glsles"; 122 else if (Ogre::HighLevelGpuProgramManager::getSingleton().isLanguageSupported("hlsl")) 123 shaderLanguage = "hlsl"; 124 else 125 MYGUI_EXCEPT("No supported shader was found. Only glsl, glsles and hlsl are implemented so far.") 126 127 mVertexProgram = Ogre::HighLevelGpuProgramManager::getSingleton().createProgram( 128 "MyGUI_VP." + shaderLanguage, 129 OgreDataManager::getInstance().getGroup(), 130 shaderLanguage, 131 Ogre::GPT_VERTEX_PROGRAM); 132 mVertexProgram->setSourceFile("MyGUI_VP." + shaderLanguage); 133 if (shaderLanguage == "hlsl") 134 { 135 mVertexProgram->setParameter("target", "vs_4_0"); 136 mVertexProgram->setParameter("entry_point", "main"); 137 } 138 mVertexProgram->load(); 139 140 mFragmentProgram = Ogre::HighLevelGpuProgramManager::getSingleton().createProgram( 141 "MyGUI_FP." + shaderLanguage, 142 OgreDataManager::getInstance().getGroup(), 143 shaderLanguage, 144 Ogre::GPT_FRAGMENT_PROGRAM); 145 mFragmentProgram->setSourceFile("MyGUI_FP." + shaderLanguage); 146 if (shaderLanguage == "hlsl") 147 { 148 mFragmentProgram->setParameter("target", "ps_4_0"); 149 mFragmentProgram->setParameter("entry_point", "main"); 150 } 151 mFragmentProgram->load(); 152 } 153 } 154 } 155 getRenderSystem()156 Ogre::RenderSystem* OgreRenderManager::getRenderSystem() 157 { 158 return mRenderSystem; 159 } 160 setRenderWindow(Ogre::RenderWindow * _window)161 void OgreRenderManager::setRenderWindow(Ogre::RenderWindow* _window) 162 { 163 mWindow = _window; 164 165 if (mWindow != nullptr) 166 { 167 if (mWindow->getNumViewports() <= mActiveViewport && 168 !mWindow->getViewport(mActiveViewport)->getOverlaysEnabled()) 169 { 170 MYGUI_PLATFORM_LOG(Warning, "Overlays are disabled. MyGUI won't render in selected viewport."); 171 } 172 173 windowResized(mWindow); 174 } 175 } 176 setSceneManager(Ogre::SceneManager * _scene)177 void OgreRenderManager::setSceneManager(Ogre::SceneManager* _scene) 178 { 179 if (nullptr != mSceneManager) 180 { 181 mSceneManager->removeRenderQueueListener(this); 182 mSceneManager = nullptr; 183 } 184 185 mSceneManager = _scene; 186 187 if (nullptr != mSceneManager) 188 { 189 mSceneManager->addRenderQueueListener(this); 190 } 191 } 192 setActiveViewport(unsigned short _num)193 void OgreRenderManager::setActiveViewport(unsigned short _num) 194 { 195 mActiveViewport = _num; 196 197 if (mWindow != nullptr) 198 { 199 if (mWindow->getNumViewports() <= mActiveViewport) 200 { 201 MYGUI_PLATFORM_LOG(Error, "Invalid active viewport index selected. There is no viewport with given index."); 202 } 203 204 // рассылка обновлений 205 windowResized(mWindow); 206 } 207 } 208 renderQueueStarted(Ogre::uint8 queueGroupId,const Ogre::String & invocation,bool & skipThisInvocation)209 void OgreRenderManager::renderQueueStarted(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& skipThisInvocation) 210 { 211 Gui* gui = Gui::getInstancePtr(); 212 if (gui == nullptr) 213 return; 214 215 if (Ogre::RENDER_QUEUE_OVERLAY != queueGroupId) 216 return; 217 218 Ogre::Viewport* viewport = mSceneManager->getCurrentViewport(); 219 if (nullptr == viewport 220 || !viewport->getOverlaysEnabled()) 221 return; 222 223 if (mWindow->getNumViewports() <= mActiveViewport 224 || viewport != mWindow->getViewport(mActiveViewport)) 225 return; 226 227 mCountBatch = 0; 228 229 static Timer timer; 230 static unsigned long last_time = timer.getMilliseconds(); 231 unsigned long now_time = timer.getMilliseconds(); 232 unsigned long time = now_time - last_time; 233 234 onFrameEvent((float)((double)(time) / (double)1000)); 235 236 last_time = now_time; 237 238 begin(); 239 onRenderToTarget(this, mUpdate); 240 //end(); 241 242 // сбрасываем флаг 243 mUpdate = false; 244 } 245 renderQueueEnded(Ogre::uint8 queueGroupId,const Ogre::String & invocation,bool & repeatThisInvocation)246 void OgreRenderManager::renderQueueEnded(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& repeatThisInvocation) 247 { 248 } 249 eventOccurred(const Ogre::String & eventName,const Ogre::NameValuePairList * parameters)250 void OgreRenderManager::eventOccurred(const Ogre::String& eventName, const Ogre::NameValuePairList* parameters) 251 { 252 if (eventName == "DeviceLost") 253 { 254 } 255 else if (eventName == "DeviceRestored") 256 { 257 // обновить всех 258 mUpdate = true; 259 } 260 } 261 createVertexBuffer()262 IVertexBuffer* OgreRenderManager::createVertexBuffer() 263 { 264 return new OgreVertexBuffer(); 265 } 266 destroyVertexBuffer(IVertexBuffer * _buffer)267 void OgreRenderManager::destroyVertexBuffer(IVertexBuffer* _buffer) 268 { 269 delete _buffer; 270 } 271 windowResized(Ogre::RenderWindow * _window)272 void OgreRenderManager::windowResized(Ogre::RenderWindow* _window) 273 { 274 if (_window->getNumViewports() > mActiveViewport) 275 { 276 Ogre::Viewport* port = _window->getViewport(mActiveViewport); 277 #if OGRE_VERSION >= MYGUI_DEFINE_VERSION(1, 7, 0) && OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0 278 Ogre::OrientationMode orient = port->getOrientationMode(); 279 if (orient == Ogre::OR_DEGREE_90 || orient == Ogre::OR_DEGREE_270) 280 setViewSize(port->getActualHeight(), port->getActualWidth()); 281 else 282 setViewSize(port->getActualWidth(), port->getActualHeight()); 283 #else 284 setViewSize(port->getActualWidth(), port->getActualHeight()); 285 #endif 286 } 287 } 288 updateRenderInfo()289 void OgreRenderManager::updateRenderInfo() 290 { 291 if (mRenderSystem != nullptr) 292 { 293 if (mRenderSystem->getName() == "Direct3D11 Rendering Subsystem") // special case, it's not working with the value returned by the rendersystem 294 { 295 mInfo.maximumDepth = 0.0f; 296 } 297 else 298 { 299 mInfo.maximumDepth = mRenderSystem->getMaximumDepthInputValue(); 300 } 301 mInfo.hOffset = mRenderSystem->getHorizontalTexelOffset() / float(mViewSize.width); 302 mInfo.vOffset = mRenderSystem->getVerticalTexelOffset() / float(mViewSize.height); 303 mInfo.aspectCoef = float(mViewSize.height) / float(mViewSize.width); 304 mInfo.pixScaleX = 1.0f / float(mViewSize.width); 305 mInfo.pixScaleY = 1.0f / float(mViewSize.height); 306 } 307 } 308 doRender(IVertexBuffer * _buffer,ITexture * _texture,size_t _count)309 void OgreRenderManager::doRender(IVertexBuffer* _buffer, ITexture* _texture, size_t _count) 310 { 311 if (_texture) 312 { 313 OgreTexture* texture = static_cast<OgreTexture*>(_texture); 314 Ogre::TexturePtr texture_ptr = texture->getOgreTexture(); 315 if (!texture_ptr.isNull()) 316 { 317 mRenderSystem->_setTexture(0, true, texture_ptr); 318 mRenderSystem->_setTextureUnitFiltering(0, Ogre::FO_LINEAR, Ogre::FO_LINEAR, Ogre::FO_NONE); 319 } 320 } 321 322 OgreVertexBuffer* buffer = static_cast<OgreVertexBuffer*>(_buffer); 323 Ogre::RenderOperation* operation = buffer->getRenderOperation(); 324 operation->vertexData->vertexCount = _count; 325 326 mRenderSystem->_render(*operation); 327 328 ++ mCountBatch; 329 } 330 begin()331 void OgreRenderManager::begin() 332 { 333 // set-up matrices 334 mRenderSystem->_setWorldMatrix(Ogre::Matrix4::IDENTITY); 335 mRenderSystem->_setViewMatrix(Ogre::Matrix4::IDENTITY); 336 337 #if OGRE_VERSION >= MYGUI_DEFINE_VERSION(1, 7, 0) && OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0 338 Ogre::OrientationMode orient = mWindow->getViewport(mActiveViewport)->getOrientationMode(); 339 mRenderSystem->_setProjectionMatrix(Ogre::Matrix4::IDENTITY * Ogre::Quaternion(Ogre::Degree(orient * 90.f), Ogre::Vector3::UNIT_Z)); 340 #else 341 mRenderSystem->_setProjectionMatrix(Ogre::Matrix4::IDENTITY); 342 #endif 343 344 // initialise render settings 345 mRenderSystem->setLightingEnabled(false); 346 mRenderSystem->_setDepthBufferParams(false, false); 347 mRenderSystem->_setDepthBias(0, 0); 348 mRenderSystem->_setCullingMode(Ogre::CULL_NONE); 349 mRenderSystem->_setFog(Ogre::FOG_NONE); 350 mRenderSystem->_setColourBufferWriteEnabled(true, true, true, true); 351 if (mRenderSystem->getCapabilities()->hasCapability(Ogre::RSC_FIXED_FUNCTION)) 352 { 353 mRenderSystem->unbindGpuProgram(Ogre::GPT_FRAGMENT_PROGRAM); 354 mRenderSystem->unbindGpuProgram(Ogre::GPT_VERTEX_PROGRAM); 355 } 356 else 357 { 358 mRenderSystem->bindGpuProgram(mVertexProgram->_getBindingDelegate()); 359 mRenderSystem->bindGpuProgram(mFragmentProgram->_getBindingDelegate()); 360 361 Ogre::GpuProgramParametersSharedPtr params = mVertexProgram->getDefaultParameters(); 362 params->setNamedConstant("YFlipScale", 1.0f); 363 mRenderSystem->bindGpuProgramParameters(Ogre::GPT_VERTEX_PROGRAM, params, Ogre::GPV_ALL); 364 } 365 mRenderSystem->setShadingType(Ogre::SO_GOURAUD); 366 367 // initialise texture settings 368 mRenderSystem->_setTextureCoordCalculation(0, Ogre::TEXCALC_NONE); 369 mRenderSystem->_setTextureCoordSet(0, 0); 370 mRenderSystem->_setTextureUnitFiltering(0, Ogre::FO_LINEAR, Ogre::FO_LINEAR, Ogre::FO_NONE); 371 mRenderSystem->_setTextureAddressingMode(0, mTextureAddressMode); 372 mRenderSystem->_setTextureMatrix(0, Ogre::Matrix4::IDENTITY); 373 #if OGRE_VERSION < MYGUI_DEFINE_VERSION(1, 6, 0) 374 mRenderSystem->_setAlphaRejectSettings(Ogre::CMPF_ALWAYS_PASS, 0); 375 #else 376 mRenderSystem->_setAlphaRejectSettings(Ogre::CMPF_ALWAYS_PASS, 0, false); 377 #endif 378 mRenderSystem->_setTextureBlendMode(0, mColorBlendMode); 379 mRenderSystem->_setTextureBlendMode(0, mAlphaBlendMode); 380 mRenderSystem->_disableTextureUnitsFrom(1); 381 382 // enable alpha blending 383 mRenderSystem->_setSceneBlending(Ogre::SBF_SOURCE_ALPHA, Ogre::SBF_ONE_MINUS_SOURCE_ALPHA); 384 385 // always use wireframe 386 // TODO: add option to enable wireframe mode in platform 387 mRenderSystem->_setPolygonMode(Ogre::PM_SOLID); 388 } 389 end()390 void OgreRenderManager::end() 391 { 392 } 393 createTexture(const std::string & _name)394 ITexture* OgreRenderManager::createTexture(const std::string& _name) 395 { 396 MapTexture::const_iterator item = mTextures.find(_name); 397 MYGUI_PLATFORM_ASSERT(item == mTextures.end(), "Texture '" << _name << "' already exist"); 398 399 OgreTexture* texture = new OgreTexture(_name, OgreDataManager::getInstance().getGroup()); 400 mTextures[_name] = texture; 401 return texture; 402 } 403 destroyTexture(ITexture * _texture)404 void OgreRenderManager::destroyTexture(ITexture* _texture) 405 { 406 if (_texture == nullptr) return; 407 408 MapTexture::iterator item = mTextures.find(_texture->getName()); 409 MYGUI_PLATFORM_ASSERT(item != mTextures.end(), "Texture '" << _texture->getName() << "' not found"); 410 411 mTextures.erase(item); 412 delete _texture; 413 } 414 getTexture(const std::string & _name)415 ITexture* OgreRenderManager::getTexture(const std::string& _name) 416 { 417 MapTexture::const_iterator item = mTextures.find(_name); 418 if (item == mTextures.end()) 419 { 420 Ogre::TexturePtr texture = (Ogre::TexturePtr)Ogre::TextureManager::getSingleton().getByName(_name); 421 if (!texture.isNull()) 422 { 423 ITexture* result = createTexture(_name); 424 static_cast<OgreTexture*>(result)->setOgreTexture(texture); 425 return result; 426 } 427 return nullptr; 428 } 429 return item->second; 430 } 431 isFormatSupported(PixelFormat _format,TextureUsage _usage)432 bool OgreRenderManager::isFormatSupported(PixelFormat _format, TextureUsage _usage) 433 { 434 return Ogre::TextureManager::getSingleton().isFormatSupported( 435 Ogre::TEX_TYPE_2D, 436 OgreTexture::convertFormat(_format), 437 OgreTexture::convertUsage(_usage)); 438 } 439 destroyAllResources()440 void OgreRenderManager::destroyAllResources() 441 { 442 for (MapTexture::const_iterator item = mTextures.begin(); item != mTextures.end(); ++item) 443 { 444 delete item->second; 445 } 446 mTextures.clear(); 447 } 448 449 #if MYGUI_DEBUG_MODE == 1 checkTexture(ITexture * _texture)450 bool OgreRenderManager::checkTexture(ITexture* _texture) 451 { 452 for (MapTexture::const_iterator item = mTextures.begin(); item != mTextures.end(); ++item) 453 { 454 if (item->second == _texture) 455 return true; 456 } 457 return false; 458 } 459 #endif 460 getViewSize() const461 const IntSize& OgreRenderManager::getViewSize() const 462 { 463 return mViewSize; 464 } 465 getVertexFormat()466 VertexColourType OgreRenderManager::getVertexFormat() 467 { 468 return mVertexFormat; 469 } 470 getInfo()471 const RenderTargetInfo& OgreRenderManager::getInfo() 472 { 473 return mInfo; 474 } 475 getActiveViewport()476 size_t OgreRenderManager::getActiveViewport() 477 { 478 return mActiveViewport; 479 } 480 getRenderWindow()481 Ogre::RenderWindow* OgreRenderManager::getRenderWindow() 482 { 483 return mWindow; 484 } 485 getManualRender()486 bool OgreRenderManager::getManualRender() 487 { 488 return mManualRender; 489 } 490 setManualRender(bool _value)491 void OgreRenderManager::setManualRender(bool _value) 492 { 493 mManualRender = _value; 494 } 495 getBatchCount() const496 size_t OgreRenderManager::getBatchCount() const 497 { 498 return mCountBatch; 499 } 500 setViewSize(int _width,int _height)501 void OgreRenderManager::setViewSize(int _width, int _height) 502 { 503 mViewSize.set(_width, _height); 504 mUpdate = true; 505 updateRenderInfo(); 506 onResizeView(mViewSize); 507 } 508 doRenderRtt(IVertexBuffer * _buffer,ITexture * _texture,size_t _count,bool flipY)509 void OgreRenderManager::doRenderRtt(IVertexBuffer* _buffer, ITexture* _texture, size_t _count, bool flipY) 510 { 511 if (flipY && !mRenderSystem->getCapabilities()->hasCapability(Ogre::RSC_FIXED_FUNCTION)) 512 { 513 Ogre::GpuProgramParametersSharedPtr params = mVertexProgram->getDefaultParameters();; 514 params->setNamedConstant("YFlipScale", -1.0f); 515 mRenderSystem->bindGpuProgramParameters(Ogre::GPT_VERTEX_PROGRAM, 516 params, Ogre::GPV_ALL); 517 } 518 519 doRender(_buffer, _texture, _count); 520 521 if (flipY && !mRenderSystem->getCapabilities()->hasCapability(Ogre::RSC_FIXED_FUNCTION)) 522 { 523 Ogre::GpuProgramParametersSharedPtr params = mVertexProgram->getDefaultParameters();; 524 params->setNamedConstant("YFlipScale", 1.0f); 525 mRenderSystem->bindGpuProgramParameters(Ogre::GPT_VERTEX_PROGRAM, 526 params, Ogre::GPV_ALL); 527 } 528 } 529 530 } // namespace MyGUI 531