Advertisement
Guest User

Noesis Ogre OpenGL example source

a guest
Oct 14th, 2013
512
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 17.13 KB | None | 0 0
  1. /*
  2.  * File:   NoesisManager.cpp
  3.  * Author: TheSHEEEP
  4.  *
  5.  * Created on 6. August 2013, 16:02
  6.  */
  7.  
  8. #include "NoesisManager.h"
  9. #include "application/PrototypeApp.h"
  10. #include "gui/MouseCursor.h"
  11. #include "gui/OgreNsGuiFileSystem.h"
  12. #include "util/MemoryLog.h"
  13. #include "util/OgreConsole.h"
  14. #include "scripting/ScriptHostMain.h"
  15. #include "OISMouse.h"
  16.  
  17. #ifdef __MINGW32__
  18.     // On Windows, using the Ogre glew header version is enough
  19.     #include <GL/glew.h>
  20. #elif __linux__
  21.     // Linux needs a bit more included and defined
  22.     #define GL_GLEXT_PROTOTYPES
  23.     #include <GL/gl.h>
  24.     #include <GL/glx.h>
  25.     #include <gui/glext.h>
  26. #endif
  27.  
  28. #include <GL/gl.h>
  29. #include <GL/glu.h>
  30. #include <GL/glext.h>
  31.  
  32. #include <boost/lexical_cast.hpp>
  33.  
  34. #include <OgreSceneManager.h>
  35. #include <OgreRoot.h>
  36.  
  37. #include <Noesis.h>
  38. #include <NsCore/Error.h>
  39. #include <NsCore/Kernel.h>
  40. #include <NsCore/NsSystem.h>
  41. #include <NsResource/IResourceSystem.h>
  42. #include <NsRender/IRenderSystem.h>
  43. #include <NsRender/StateObjects.h>
  44. #include <NsGui/UIElement.h>
  45. #include <NsGui/Button.h>
  46. #include <NsGui/TextBlock.h>
  47. #include <NsGui/Image.h>
  48. #include <NsGui/ImageSource.h>
  49.  
  50. MemoryLog* NoesisManager::_logger = 0;
  51.  
  52. EXPORT_OOLUA_FUNCTIONS_NON_CONST(NoesisManager, bindFunctionToButtonClick, setJumping)
  53. EXPORT_OOLUA_FUNCTIONS_CONST(NoesisManager)
  54.  
  55. //--------------------------------------------------------------------------------------------------
  56. NoesisManager::NoesisManager()
  57.     : _sceneMgr(0)
  58.     , _root(0)
  59.     , _width(0)
  60.     , _height(0)
  61.     , _callbackRegistry(0)
  62. {
  63. }
  64.  
  65. //--------------------------------------------------------------------------------------------------
  66. NoesisManager::~NoesisManager()
  67. {
  68. }
  69.  
  70. //--------------------------------------------------------------------------------------------------
  71. bool
  72. NoesisManager::setup(Ogre::SceneManager* p_sceneMgr, Ogre::Root* p_root, MemoryLog* p_logger, OIS::Mouse* p_mouse,
  73.                      int p_width, int p_height)
  74. {
  75.     _sceneMgr = p_sceneMgr;
  76.     _root = p_root;
  77.     _mouse = p_mouse;
  78.     p_mouse->setEventCallback(this);
  79.    
  80.     _root->getRenderSystem()->addListener(this);
  81.  
  82.     if (_sceneMgr)
  83.     {
  84.         _sceneMgr->addRenderQueueListener(this);
  85.     }
  86.    
  87.     // Get required Ogre pointers
  88.     _logger = p_logger;
  89.    
  90.     // Init Noesis kernel
  91.     Noesis::Core::SetErrorHandler(handleNoesisError);
  92.     NsGetKernel()->Init();
  93.    
  94.     // Register own classes
  95.     // NsRegisterReflection(NsGetKernel()->GetComponentFactory(), true);
  96.    
  97.     // Register file system and add folders
  98.     _ogreFileSystem = new Noesis::Gui::OgreNsGuiFileSystem();
  99.     Ogre::ResourceGroupManager::getSingleton().addResourceLocation("../../assets/gui", "FileSystem", "Gui");
  100.     Ogre::ResourceGroupManager::getSingleton().addResourceLocation("../../assets/gui/Drawing/VGL", "FileSystem", "Gui");
  101.     Ogre::ResourceGroupManager::getSingleton().addResourceLocation("../../assets/gui/Gui/Core", "FileSystem", "Gui");
  102.     Ogre::ResourceGroupManager::getSingleton().addResourceLocation("../../assets/gui/Gui/Themes", "FileSystem", "Gui");
  103.     Ogre::ResourceGroupManager::getSingleton().addResourceLocation("../../assets/gui/Survivor/Test", "FileSystem", "Gui");
  104.     Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup("Gui");    
  105.     Noesis::Resource::IResourceSystem::SetFileSystem(_ogreFileSystem);
  106.    
  107.     // Init systems
  108.     NsGetKernel()->InitSystems();
  109.    
  110.     // Load our own xaml file
  111.     _xamlRoot =
  112.             Noesis::Gui::LoadXaml<Noesis::Gui::FrameworkElement>("Survivor/Test/TestWindow.xaml");    
  113.    
  114.     // Create noesis renderer
  115.     _noesisGLRenderer = Noesis::Gui::CreateRenderer(_xamlRoot.GetPtr());
  116.     _noesisGLRenderer->SetAntialiasingMode(Noesis::Gui::AntialiasingMode_PPAA);
  117.     _noesisGLRenderer->SetSize(p_width, p_height);
  118.    
  119.     // Create callback registry
  120.     _callbackRegistry = new DynamicCallbackRegistry();
  121.     _callbackRegistry->setup();
  122.    
  123.     _width = p_width;
  124.     _height = p_height;
  125.    
  126.     // Create mouse cursor
  127.     _mouseCursor = new MouseCursor();
  128.     _mouseCursor->setImage("mouseCursor.png");
  129.     _mouseCursor->setVisible(true);
  130.     _mouseCursor->setWindowDimensions(_width, _height);
  131.    
  132.     return true;
  133. }
  134.  
  135. //--------------------------------------------------------------------------------------------------
  136. void
  137. NoesisManager::shutdown()
  138. {
  139.     _root->getRenderSystem()->removeListener(this);
  140.  
  141.     if (_sceneMgr)
  142.     {
  143.         _sceneMgr->removeRenderQueueListener(this);
  144.     }
  145.    
  146.     _renderCommands.commands.Reset();    
  147.     _renderCommands.offscreenCommands.Reset();
  148.    
  149.     _noesisGLRenderer.Reset();
  150.    
  151.     _xamlRoot.Reset();
  152.     NsGetKernel()->Shutdown();
  153. }
  154.  
  155. //--------------------------------------------------------------------------------------------------
  156. bool
  157. NoesisManager::mouseMoved(const OIS::MouseEvent& p_mouseEvent)
  158. {
  159.     _mouseCursor->updatePosition(p_mouseEvent.state.X.abs, p_mouseEvent.state.Y.abs);
  160.     _noesisGLRenderer->MouseMove(p_mouseEvent.state.X.abs, p_mouseEvent.state.Y.abs);
  161.    
  162.     return true;
  163. }
  164.  
  165. //--------------------------------------------------------------------------------------------------
  166. bool
  167. NoesisManager::mousePressed(const OIS::MouseEvent& p_mouseEvent, OIS::MouseButtonID p_id)
  168. {
  169.     switch (p_id)
  170.     {
  171.         case OIS::MB_Left:
  172.             _noesisGLRenderer->MouseButtonDown(p_mouseEvent.state.X.abs, p_mouseEvent.state.Y.abs,
  173.                     Noesis::Gui::MouseButton_Left);
  174.             break;
  175.            
  176.         case OIS::MB_Right:
  177.             _noesisGLRenderer->MouseButtonDown(p_mouseEvent.state.X.abs, p_mouseEvent.state.Y.abs,
  178.                     Noesis::Gui::MouseButton_Right);
  179.             break;
  180.            
  181.         default:
  182.             break;
  183.     }
  184.    
  185.     return true;
  186. }
  187.  
  188. //--------------------------------------------------------------------------------------------------
  189. bool
  190. NoesisManager::mouseReleased(const OIS::MouseEvent& p_mouseEvent, OIS::MouseButtonID p_id)
  191. {
  192.     switch (p_id)
  193.     {
  194.         case OIS::MB_Left:
  195.             _noesisGLRenderer->MouseButtonUp(p_mouseEvent.state.X.abs, p_mouseEvent.state.Y.abs,
  196.                     Noesis::Gui::MouseButton_Left);
  197.             break;
  198.            
  199.         case OIS::MB_Right:
  200.             _noesisGLRenderer->MouseButtonUp(p_mouseEvent.state.X.abs, p_mouseEvent.state.Y.abs,
  201.                     Noesis::Gui::MouseButton_Right);
  202.             break;
  203.            
  204.         default:
  205.             break;
  206.     }
  207.    
  208.     return true;
  209. }
  210.    
  211. //--------------------------------------------------------------------------------------------------
  212. void
  213. NoesisManager::handleNoesisError(const NsChar* p_filename, NsInt p_line, const NsChar* p_desc)
  214. {
  215.     std::string message = "Noesis Error: File: ";
  216.     message.append(p_filename);
  217.     message.append(" Line: ");
  218.     message.append(boost::lexical_cast<std::string>(p_line));
  219.     message.append("\n Description: ");
  220.     message.append(p_desc);
  221.     _logger->logMessageCritical(message);
  222. }
  223.  
  224. //--------------------------------------------------------------------------------------------------
  225. void
  226. NoesisManager::renderQueueStarted(Ogre::uint8 p_queueGroupId,
  227.                                     const Ogre::String& p_invocation, bool& p_skipThisInvocation)
  228. {
  229.     // We're going to render ourselves in the Overlay Queue so we're always on top
  230.     if(p_queueGroupId == Ogre::RENDER_QUEUE_OVERLAY)
  231.     {
  232.         doPostSceneStep();
  233.        
  234.         restoreRenderStates();
  235.     }
  236. }
  237.  
  238. //--------------------------------------------------------------------------------------------------
  239. void
  240. NoesisManager::doPreSceneStep(const double& p_timeSinceLastFrame)
  241. {
  242.     // Tick
  243.     NsGetKernel()->Tick();
  244.    
  245.     static double time = 0.0;
  246.     time += p_timeSinceLastFrame;
  247.    
  248.     // Update with time and wait for update to finish
  249.     // TODO: We should have time since last frame stored somewhere globally accessible
  250.     _noesisGLRenderer->Update(time);
  251.     // TODO: We could do something useful here
  252.     _renderCommands = _noesisGLRenderer->WaitForUpdate();
  253.  
  254.     // Do the offscreen rendering
  255.     _noesisGLRenderer->Render(_renderCommands.offscreenCommands.GetPtr());
  256.    
  257.     restoreRenderStates();
  258. }
  259.  
  260. //--------------------------------------------------------------------------------------------------
  261. void
  262. NoesisManager::doPostSceneStep()
  263. {
  264.     storeCurrentRenderStates();
  265.    
  266.     // Do the onscreen rendering
  267.     _noesisGLRenderer->Render(_renderCommands.commands.GetPtr());
  268. }
  269.  
  270. //--------------------------------------------------------------------------------------------------
  271. void
  272. NoesisManager::storeCurrentRenderStates()
  273. {
  274.     // Matrices
  275. //    glMatrixMode(GL_MODELVIEW);
  276. //    glPushMatrix();
  277. //    glMatrixMode(GL_PROJECTION);
  278. //    glPushMatrix();
  279. //    glMatrixMode(GL_TEXTURE);
  280. //    glPushMatrix();
  281. //    glLoadIdentity(); //Texture addressing should start out as direct.
  282.        
  283.     // Render states
  284.     glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_rsStorage.frameBuffer);
  285.    
  286.     glGetFloatv(GL_COLOR_CLEAR_VALUE, _rsStorage.clearColors);
  287.     glGetFloatv(GL_DEPTH_CLEAR_VALUE, &_rsStorage.clearDepth);
  288.    
  289.     glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &_rsStorage.clearStencil);
  290.     _rsStorage.depthTest = glIsEnabled(GL_DEPTH_TEST);
  291.     glGetBooleanv(GL_DEPTH_WRITEMASK, &_rsStorage.depthWrite);
  292.     glGetIntegerv(GL_DEPTH_FUNC, &_rsStorage.depthFunc);
  293.    
  294.     _rsStorage.stencilTest = glIsEnabled(GL_STENCIL_TEST);
  295.     glGetIntegerv(GL_STENCIL_FAIL, &_rsStorage.stencilTestFailOp);
  296.     glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &_rsStorage.stencilTestSPDF);
  297.     glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &_rsStorage.stencilTestSPDP);
  298.     glGetIntegerv(GL_STENCIL_FUNC, &_rsStorage.stencilFunc);
  299.     glGetIntegerv(GL_STENCIL_REF, &_rsStorage.stencilRef);
  300.     glGetIntegerv(GL_STENCIL_VALUE_MASK, (int*)&_rsStorage.stencilMask);
  301.     glGetIntegerv(GL_STENCIL_WRITEMASK, (int*)&_rsStorage.stencilWriteMask);
  302.    
  303.     _rsStorage.scissorTest = glIsEnabled(GL_SCISSOR_TEST);
  304.     _rsStorage.cullFaceEnabled = glIsEnabled(GL_CULL_FACE);
  305.     glGetIntegerv(GL_CULL_FACE_MODE, &_rsStorage.cullFaceMode);
  306.    
  307.     _rsStorage.blendEnabled = glIsEnabled(GL_BLEND);
  308.     glGetIntegerv(GL_BLEND_EQUATION_RGB, &_rsStorage.blendEquationRGB);
  309.     glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &_rsStorage.blendEquationA);
  310.     glGetIntegerv(GL_BLEND_SRC_RGB, &_rsStorage.blendSource);
  311.     glGetIntegerv(GL_BLEND_DST_RGB, &_rsStorage.blendDestination);
  312.    
  313.     glGetBooleanv(GL_COLOR_WRITEMASK, _rsStorage.colorWriteMask);
  314.    
  315. //    glPushAttrib(GL_ALL_ATTRIB_BITS);
  316.    
  317.     // Buffers
  318.     glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (int*)&_rsStorage.arrayBuffer);
  319.     glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, (int*)&_rsStorage.maxVertexAttribs);
  320.     for (NsSize i = 0; i < _rsStorage.maxVertexAttribs; i++)
  321.     {
  322.         glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &(_rsStorage.vertexAttribsEnabled[i]));
  323.     }
  324.    
  325.     glGetIntegerv(GL_ACTIVE_TEXTURE, &_rsStorage.activeTexture);
  326.    
  327.     glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, (int*)&_rsStorage.elementArrayBuffer);
  328.     glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, (int*)&_rsStorage.maxTextureUnits);
  329.     for (NsSize i = 0; i < 4; i++)
  330.     {
  331.         glActiveTexture(GL_TEXTURE0 + i);
  332.         glGetIntegerv(GL_TEXTURE_BINDING_2D, &(_rsStorage.boundTexture[i]));
  333.     }
  334.    
  335.     glGetIntegerv(GL_CURRENT_PROGRAM, &_rsStorage.currentProgram);
  336.     glGetIntegerv(GL_UNPACK_ALIGNMENT, &_rsStorage.unpackAlignment);
  337.    
  338.     _rsStorage.hasState = true;
  339. }
  340.  
  341. //--------------------------------------------------------------------------------------------------
  342. void
  343. NoesisManager::restoreRenderStates()
  344. {
  345.     if (!_rsStorage.hasState)
  346.         return;
  347.    
  348.     glPixelStorei(GL_UNPACK_ALIGNMENT, _rsStorage.unpackAlignment);
  349.     glUseProgram(_rsStorage.currentProgram);
  350.    
  351.     // Buffers
  352.     glBindBuffer(GL_ARRAY_BUFFER, _rsStorage.arrayBuffer);
  353.     for (NsSize i = 0; i < _rsStorage.maxVertexAttribs; i++)
  354.     {
  355.         _rsStorage.vertexAttribsEnabled[i] ? glEnableVertexAttribArray(i) : glDisableVertexAttribArray(i);
  356.     }
  357.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _rsStorage.elementArrayBuffer);
  358.     for (NsSize i = 0; i < 4; i++)
  359.     {
  360.         glActiveTexture(GL_TEXTURE0 + i);
  361.         glBindTexture(GL_TEXTURE_2D, _rsStorage.boundTexture[i]);
  362.     }
  363.    
  364.     glActiveTexture(_rsStorage.activeTexture);
  365.    
  366.     //Render states
  367.     glClearColor(_rsStorage.clearColors[0], _rsStorage.clearColors[1], _rsStorage.clearColors[2],
  368.             _rsStorage.clearColors[3]);
  369.     glClearDepth(_rsStorage.clearDepth);
  370.     glClearStencil(_rsStorage.clearStencil);
  371.    
  372.     _rsStorage.depthTest ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
  373.     glDepthMask(_rsStorage.depthWrite);
  374.     glDepthFunc(_rsStorage.depthFunc);
  375.    
  376.     _rsStorage.stencilTest ? glEnable(GL_STENCIL_TEST) : glDisable(GL_STENCIL_TEST);
  377.     glStencilOp(_rsStorage.stencilTestFailOp, _rsStorage.stencilTestSPDF, _rsStorage.stencilTestSPDP);
  378.     glStencilFunc(_rsStorage.stencilFunc, _rsStorage.stencilRef, _rsStorage.stencilMask);
  379.     glStencilMask(_rsStorage.stencilWriteMask);
  380.    
  381.     _rsStorage.scissorTest ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST);
  382.     _rsStorage.cullFaceEnabled ? glEnable(GL_CULL_FACE) : glDisable(GL_CULL_FACE);
  383.     glCullFace(_rsStorage.cullFaceMode);
  384.    
  385.     _rsStorage.blendEnabled ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
  386.     glBlendEquationSeparate(_rsStorage.blendEquationRGB, _rsStorage.blendEquationA);
  387.     glBlendFunc(_rsStorage.blendSource, _rsStorage.blendDestination);
  388.    
  389.     glColorMask(_rsStorage.colorWriteMask[0], _rsStorage.colorWriteMask[1], _rsStorage.colorWriteMask[2],
  390.             _rsStorage.colorWriteMask[3]);
  391.    
  392. //    glPopAttrib();
  393.    
  394.     // Restore matrices
  395. //    glMatrixMode(GL_TEXTURE);
  396. //    glPopMatrix();
  397. //    glMatrixMode(GL_PROJECTION);
  398. //    glPopMatrix();
  399. //    glMatrixMode(GL_MODELVIEW);
  400. //    glPopMatrix();
  401.  
  402.     // Restore frame buffer and viewport
  403.     glBindFramebuffer(GL_FRAMEBUFFER, _rsStorage.frameBuffer);  
  404.     glViewport(0, 0, _width, _height);
  405. }
  406.    
  407. //--------------------------------------------------------------------------------------------------
  408. void
  409. NoesisManager::bindFunctionToButtonClick(std::string p_buttonName, OOLUA::Lua_func_ref p_luaFunc)
  410. {
  411.     // Check if there is a button with that name
  412.     Noesis::Gui::Button* button = (Noesis::Gui::Button*)_xamlRoot->FindName(p_buttonName.c_str());
  413.     if (button == 0)
  414.     {
  415.         CONSOLE_LOG("Button named \"" + p_buttonName + "\" doesn't exist.");
  416.         return;
  417.     }
  418.    
  419.     // Add dynamic type and register Callback at script host
  420.     _callbackRegistry->addDynamicType(p_buttonName);
  421.     PrototypeApp::Singleton->getScriptHost()
  422.             ->registerCallbackExternalDynamic(p_buttonName, p_luaFunc, _callbackRegistry);
  423.    
  424.     // FIXME: prevent double delegate adding, or does Noesis do that automatically?
  425.     button->Click() += Noesis::Core::MakeDelegate(this, &NoesisManager::handleButtonClick);
  426. }
  427.  
  428. //--------------------------------------------------------------------------------------------------
  429. void
  430. NoesisManager::setJumping(bool p_isJumping)
  431. {
  432.     Noesis::Gui::TextBlock* status = (Noesis::Gui::TextBlock*)_xamlRoot->FindName("txtStatus");
  433.     Noesis::Gui::Image* imageNorm = (Noesis::Gui::Image*)_xamlRoot->FindName("imgNorm");
  434.     Noesis::Gui::Image* imageJump = (Noesis::Gui::Image*)_xamlRoot->FindName("imgJump");
  435.    
  436.     if (p_isJumping)
  437.     {
  438.         imageNorm->SetVisibility(Noesis::Gui::Visibility_Collapsed);
  439.         imageJump->SetVisibility(Noesis::Gui::Visibility_Visible);
  440.         status->SetText("Wheeeeee!!!");
  441.     }
  442.     else
  443.     {
  444.         imageJump->SetVisibility(Noesis::Gui::Visibility_Collapsed);
  445.         imageNorm->SetVisibility(Noesis::Gui::Visibility_Visible);
  446.         status->SetText("I am OK!");
  447.     }
  448. }
  449.  
  450. //--------------------------------------------------------------------------------------------------
  451. void
  452. NoesisManager::handleButtonClick(Noesis::Core::BaseComponent* p_baseComp, const Noesis::Gui::RoutedEventArgs& p_args)
  453. {
  454.     Noesis::Gui::Button* button = (Noesis::Gui::Button*)p_baseComp;
  455.    
  456.     PrototypeApp::Singleton->getScriptHost()
  457.             ->triggerCallbackExternalDynamic(button->GetName().c_str(), _callbackRegistry);
  458. }
  459.  
  460. //--------------------------------------------------------------------------------------------------
  461. void
  462. NoesisManager::eventOccurred(const Ogre::String& p_eventName, const Ogre::NameValuePairList* p_parameters)
  463. {
  464.     if (p_eventName == "DeviceLost")
  465.     {
  466.         deviceLostCallback();
  467.     }
  468.     else if(p_eventName == "DeviceRestored")
  469.     {
  470.         deviceResetCallback();
  471.     }
  472. }
  473.  
  474. //--------------------------------------------------------------------------------------------------
  475. void
  476. NoesisManager::deviceLostCallback()
  477. {
  478. //    NsGetSystem<Noesis::Render::IRenderSystem>()->OnLostDevice();
  479. }
  480.  
  481.  
  482. //--------------------------------------------------------------------------------------------------
  483. void
  484. NoesisManager::deviceResetCallback()
  485. {
  486. //     NsGetSystem<Noesis::Render::IRenderSystem>()->OnResetDevice();
  487. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement