OGRE Wiki
Support and community documentation for Ogre3D
Ogre Forums
ogre3d.org
Log in
Username:
Password:
CapsLock is on.
Remember me (for 1 year)
Log in
Home
Tutorials
Tutorials Home
Basic Tutorials
Intermediate Tutorials
Mad Marx Tutorials
In Depth Tutorials
Older Tutorials
External Tutorials
Cookbook
Cookbook Home
CodeBank
Snippets
Experiences
Ogre Articles
Libraries
Libraries Home
Alternative Languages
Assembling A Toolset
Development Tools
OGRE Libraries
List of Libraries
Tools
Tools Home
DCC Tools
DCC Tutorials
DCC Articles
DCC Resources
Assembling a production pipeline
Development
Development Home
Roadmap
Building Ogre
Installing the Ogre SDK
Setting Up An Application
Ogre Wiki Tutorial Framework
Frequently Asked Questions
Google Summer Of Code
Help Requested
Ogre Core Articles
Community
Community Home
Projects Using Ogre
Recommended Reading
Contractors
Wiki
Immediate Wiki Tasklist
Wiki Ideas
Wiki Guidelines
Article Writing Guidelines
Wiki Styles
Wiki Page Tracker
Ogre Wiki Help
Ogre Wiki Help Overview
Help - Basic Syntax
Help - Images
Help - Pages and Structures
Help - Wiki Plugins
Toolbox
Freetags
Categories
List Pages
Structures
Trackers
Statistics
Rankings
List Galleries
Ogre Lexicon
Comments
History: WxOgre for OGRE v1.2
View page
Source of version: 3
(current)
This document is outdated, make sure you read ((WxOgre for OGRE v1.4)) {maketoc} !!wxOgre for OGRE v1.2 This article provides an example of how OGRE and wxWidgets can work together in one application. This can be very useful when writing tools such as 3D world editors or 3D viewers. The following C++ class is a quick and simple wxControl derived object that can be easily used with the GUI toolkit wxWidgets. It is defined as singleton and currently only supports a single OGRE window. Originally posted [http://www.groteskandmonstrous.com/code/index.php?option=com_content&task=view&id=16&Itemid=2|here]. OGRE Forums Thread [http://www.ogre3d.org/phpBB2/viewtopic.php?t=20652|here]. !!!Requirements * OGRE 1.2 [Dagon] * wxWidgets !!!Limitations * Supports a single OGRE window only * Fully tested on Windows OS. Linux support is there but needs testing (if somebody was able to get this to work on MacOS please add your code). !!!Memory Manager Note Just like Ogre, wxWidgets uses a memory manager. To avoid collision between the two memory managers, you can do one of the following: * Recompile Ogre from source without the debug memory manager: Add __#define OGRE_DEBUG_MEMORY_MANAGER 0__ in __OgreConfig.h__ and build Ogre. * If you want to avoid recompiling and use the precompiled OgreSDK, follow these steps: ** In OgreMemoryManager.h comment out these lines (lines 353-373) {CODE(wrap="1", colors="c++")}inline void *operator new(size_t reportedSize) { if( !gProcessID ) gProcessID = Ogre::MemoryManager::instance()._getProcessID(); return Ogre::MemoryManager::instance().op_new_sc( reportedSize, gProcessID ); } inline void *operator new[](size_t reportedSize) { if( !gProcessID ) gProcessID = Ogre::MemoryManager::instance()._getProcessID(); return Ogre::MemoryManager::instance().op_new_vc( reportedSize, gProcessID ); } inline void operator delete(void *reportedAddress) { Ogre::MemoryManager::instance().op_del_sc( reportedAddress, gProcessID ); } inline void operator delete[](void *reportedAddress) { Ogre::MemoryManager::instance().op_del_vc( reportedAddress, gProcessID ); }{CODE} ** And replace the line 381 {CODE(wrap="1", colors="c++")}#include "OgreMemoryMacros.h"{CODE} with {CODE(wrap="1", colors="c++")}#include "OgreNoMemoryMacros.h"{CODE} !!!Code __wxOgre.h__ {CODE(wrap="1", colors="c++")}#ifndef __WXOGRE_H__ #define __WXOGRE_H__ #include "Ogre.h" #include "wx/wx.h" #include <OgreNoMemoryMacros.h> #include <OgreMemoryMacros.h> /** @brief WX widget for and Ogre rendering window This WX widget is a self-contained SINGLETON Ogre rendering window; meaning it contains all Ogre objects necessary to create a rendering window and currently supports only one rendering window at a time! This is due to the limitation of the self contained class. @usage Simply create a new wxOgre object and pass a wxFrame as its parent window. Then work with it just like ay other wxControl object. It can even be passed to an wxAUI pane. */ class wxOgre : public wxControl, public Ogre::Singleton<wxOgre> { DECLARE_CLASS(wxOgre) public: /** A new wxOgre must receive a parent frame to which to attach itself to */ wxOgre (wxFrame* parent); ~wxOgre(); /** Renders a single Ogre frame */ void update(); /** Returns the currently used camera */ inline Ogre::Camera* getCamera(){return mCamera;} /** Sets a new camera for rendering */ inline void setCamera(Ogre::Camera* camera){mCamera = camera;} protected: DECLARE_EVENT_TABLE() private: /** Creates an ogre rendering window and all other default objects such as the Ogre Root, default camera, default scene manager etc */ void createOgreRenderWindow(); /** Toggles the rendering timer on/off */ void toggleTimerRendering(); /** Callback function to a window resize event */ void OnSize(wxSizeEvent& event); /** Callback function to a window paint event */ void OnPaint(wxPaintEvent& event); /** Callback function to an EraseBackground event */ void OnEraseBackground( wxEraseEvent& ); /** Callback function to a timer "tick" event */ void OnRenderTimer(wxTimerEvent& event); /* WX members */ /** Rendering timer */ wxTimer mTimer; /* Ogre members */ /** Local Ogre::Root pointer */ Ogre::Root* mRoot; /** Local Ogre::Viewport pointer */ Ogre::Viewport* mViewPort; /** Local Ogre::Camera pointer */ Ogre::Camera* mCamera; /** Local Ogre::SceneManager pointer */ Ogre::SceneManager* mSceneMgr; /** Local Ogre::RenderWindow pointer */ Ogre::RenderWindow* mRenderWindow; public: // ***************************************************** // ----------------------------------------------------- /** @remarks Why do we do this? Well, it's because the Singleton implementation is in a .h file, which means it gets compiled into anybody who includes it. This is needed for the Singleton template to work, but we actually only want it compiled into the implementation of the class based on the Singleton, not all of them. If we don't change this, we get link errors when trying to use the Singleton-based class from an outside dll. @par This method just delegates to the template version anyway, but the implementation stays in this single compilation unit, preventing link errors. */ static wxOgre& getSingleton(); /** @remarks Why do we do this? Well, it's because the Singleton implementation is in a .h file, which means it gets compiled into anybody who includes it. This is needed for the Singleton template to work, but we actually only want it compiled into the implementation of the class based on the Singleton, not all of them. If we don't change this, we get link errors when trying to use the Singleton-based class from an outside dll. @par This method just delegates to the template version anyway, but the implementation stays in this single compilation unit, preventing link errors. */ static wxOgre* getSingletonPtr(); }; #endif // __WXOGRE_H__{CODE} __wxOgre.cpp__ {CODE(wrap="1", colors="c++")}#include "wxOgre.h" #ifdef __WXGTK__ #include <gdk/gdk.h> #include <gtk/gtk.h> // just this should suffice as it should include gdk.h itself #endif // Required for the timer const long ID_RENDERTIMER = wxNewId(); // Required for WX IMPLEMENT_CLASS(wxOgre, wxControl) // Required for WX BEGIN_EVENT_TABLE(wxOgre, wxControl) EVT_SIZE(wxOgre::OnSize) // EVT_PAINT(wxOgre::OnPaint) // Produces flickers and runs too fast! EVT_ERASE_BACKGROUND( wxOgre::OnEraseBackground ) EVT_TIMER( ID_RENDERTIMER, wxOgre::OnRenderTimer ) END_EVENT_TABLE() wxOgre::wxOgre(wxFrame* parent) : wxControl(parent, -1), mTimer(this, ID_RENDERTIMER), mRoot(0), mViewPort(0), mCamera(0), mSceneMgr(0), mRenderWindow(0) { // Create all Ogre objects createOgreRenderWindow(); // Start the rendering timer toggleTimerRendering(); } void wxOgre::createOgreRenderWindow() { // Create a new Ogre ROOT mRoot = new Ogre::Root(); Ogre::Root::getSingleton().restoreConfig(); mRenderWindow = Ogre::Root::getSingleton().initialise(false); // -------------------- // Create a new parameters list according to compiled OS Ogre::NameValuePairList params; Ogre::String handle; #ifdef __WXMSW__ handle = Ogre::StringConverter::toString((size_t)((HWND)GetHandle())); #elif defined(__WXGTK__) // TODO: Someone test this. you might to use "parentWindowHandle" if this // does not work. Ogre 1.2 + Linux + GLX platform wants a string of the // format display:screen:window, which has variable types ulong:uint:ulong. GtkWidget* widget = GetHandle(); gtk_widget_realize( widget ); // Mandatory. Otherwise, a segfault happens. std::stringstream handleStream; Display* display = GDK_WINDOW_XDISPLAY( widget->window ); Window wid = GDK_WINDOW_XWINDOW( widget->window ); // Window is a typedef for XID, which is a typedef for unsigned int /* Get the right display (DisplayString() returns ":display.screen") */ std::string displayStr = DisplayString( display ); displayStr = displayStr.substr( 1, ( displayStr.find( ".", 0 ) - 1 ) ); /* Put all together */ handleStream << displayStr << ':' << DefaultScreen( display ) << ':' << wid; handle = handleStream.str(); #else #error Not supported on this platform. #endif params["externalWindowHandle"] = handle; // Get wx control window size int width; int height; GetSize(&width, &height); // Create the render window mRenderWindow = Ogre::Root::getSingleton().createRenderWindow("OgreRenderWindow", width, height, false, ¶ms); // -------------------- // Create the SceneManager, in this case a generic one mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC, "ExampleSMInstance"); // -------------------- // Create the camera mCamera = mSceneMgr->createCamera("PlayerCam"); // Position it at 500 in Z direction mCamera->setPosition(Ogre::Vector3(0,0,500)); // Look back along -Z mCamera->lookAt(Ogre::Vector3(0,0,-300)); mCamera->setNearClipDistance(5); // Set the viewport mViewPort = mRenderWindow->addViewport(mCamera); mViewPort->setBackgroundColour(Ogre::ColourValue(1.0f, 0.0f, 0.0f, 1.0f)); } void wxOgre::toggleTimerRendering() { // Toggle Start/Stop if (mTimer.IsRunning()) mTimer.Stop(); mTimer.Start(10); } wxOgre::~wxOgre() { // destroy Viewport and RenderWindow if (mViewPort) { mRenderWindow->removeViewport(mViewPort->getZOrder()); mViewPort = 0; } Ogre::Root::getSingleton().detachRenderTarget(mRenderWindow); mRenderWindow = 0; } void wxOgre::OnSize(wxSizeEvent& event) { // Setting new size; int width; int height; GetSize(&width, &height); mRenderWindow->resize( width, height ); // Letting Ogre know the window has been resized; mRenderWindow->windowMovedOrResized(); // Set the aspect ratio for the new size; if (mCamera) mCamera->setAspectRatio(Ogre::Real(width) / Ogre::Real(height)); update(); } void wxOgre::OnPaint(wxPaintEvent& event) { // update(); // Produces flickers and runs too fast! } void wxOgre::OnEraseBackground( wxEraseEvent& ) { update(); } void wxOgre::OnRenderTimer(wxTimerEvent& event) { update(); } void wxOgre::update() { // **************************************************** // TODO: REMOVE THESE LINES! These are merely for test! static float redTone = 0; redTone += 0.01; if(redTone>1.0) redTone=0; // **************************************************** mViewPort->setBackgroundColour(Ogre::ColourValue(redTone, 0.0f, 0.0f, 1.0f)); Ogre::Root::getSingletonPtr()->renderOneFrame(); } template<> wxOgre* Ogre::Singleton<wxOgre>::ms_Singleton = 0; wxOgre& wxOgre::getSingleton() { return ( *ms_Singleton ); } wxOgre* wxOgre::getSingletonPtr() { return ms_Singleton; }{CODE} !!!Usage - Example with wxAUI __MainFrame.h__ {CODE(wrap="1", colors="c++")}#ifndef __MAINFRAME_H__ #define __MAINFRAME_H__ #include "wx/wx.h" #include "wx/aui/aui.h" #include "wxOgre.h" class MainFrame : public wxFrame { public: MainFrame(wxWindow* parent) : wxFrame(parent, -1, _("wxAUI Test"), wxDefaultPosition, wxSize(800,600), wxDEFAULT_FRAME_STYLE) { // notify wxAUI which frame to use m_mgr.SetFrame(this); // create several text controls wxTextCtrl* text1 = new wxTextCtrl(this, -1, _("Pane 1 - sample text"), wxDefaultPosition, wxSize(200,150), wxNO_BORDER | wxTE_MULTILINE); wxTextCtrl* text2 = new wxTextCtrl(this, -1, _("Pane 2 - sample text"), wxDefaultPosition, wxSize(200,150), wxNO_BORDER | wxTE_MULTILINE); wxTextCtrl* text3 = new wxTextCtrl(this, -1, _("Main content window"), wxDefaultPosition, wxSize(200,150), wxNO_BORDER | wxTE_MULTILINE); // add the panes to the manager m_mgr.AddPane(text1, wxLEFT, wxT("Pane Number One")); m_mgr.AddPane(text2, wxBOTTOM, wxT("Pane Number Two")); m_mgr.AddPane(text3, wxTOP); // ************************ wxOgrePane = new wxOgre(this); m_mgr.AddPane(wxOgrePane, wxCENTER, wxT("Ogre Pane")); // tell the manager to "commit" all the changes just made m_mgr.Update(); } ~MainFrame() { // deinitialize the frame manager m_mgr.UnInit(); } void UpdateOgre() { wxOgrePane->update(); } private: wxAuiManager m_mgr; wxOgre* wxOgrePane; }; // our normal wxApp-derived class, as usual class MyApp : public wxApp { public: MainFrame* frame; bool OnInit() { frame = new MainFrame(NULL); SetTopWindow(frame); frame->Show(); frame->UpdateOgre(); return true; } }; DECLARE_APP(MyApp); IMPLEMENT_APP(MyApp); #endif //__MAINFRAME_H__{CODE}
Search by Tags
Search Wiki by Freetags
Latest Changes
Minimal Ogre Collision
Artifex Terra
OpenMB
Advanced Mogre Framework
MogreSocks
Critter AI
Mogre Add-ons
MOGRE
Mogre MyGUI wrapper
MOGRE Editable Terrain Manager
...more
Search
Find
Advanced
Search Help
Online Users
36 online users