Integrating OpenGUI

From Ogre Wiki

Jump to: navigation, search

OpenGUI is a GUI library, written by an Ogre user, so he has also created an Ogre renderer for it.
This is a code snippet that initializes the OpenGUI environment with the relevant Ogre objects and displays a screen layout loaded from XML. It shows basic integration of OpenGUI in an Ogre project :

/*
	Trivial OpenGUI (0.8) Screen viewer.
	File containing screen has to be "OpenGuiTest.xml"
	Screen name has to be "DesignScreen"
	F5 to refresh screen after making changes while running
	Assumes that the file has the amethyst plugin and only that
	ESC to exit.
	Enjoy.
*/

#define GUI_SCREEN_FILE_NAME "OpenGuiTest.xml"
#define GUI_SCREEN_NAME "DesignScreen"

#include "ExampleApplication.h"
#include <OpenGUI.h>
#include <Renderer_Ogre.h>

//Trivial class just to not seperate this app into files.
class Refresher 
{
public:
	virtual void refreshScreen() {}
};


class RefresherFrameListener : public ExampleFrameListener
{
public:
	RefresherFrameListener( RenderWindow* win, Camera* cam, SceneManager *sceneMgr, Refresher* refresher)
		: ExampleFrameListener(win, cam, false, false)
	{
		// key and mouse state tracking
		mRefreshDown = false;
		mRefresher = refresher;
	}

	bool frameStarted(const FrameEvent &evt)
	{	
		mInputDevice->capture();
		if (mRefreshDown == false && mInputDevice->isKeyDown(KC_F5)) 
		{
			mRefresher->refreshScreen();
		}
		mRefreshDown = mInputDevice->isKeyDown(KC_F5);
		//If we press escape, return.
		return !mInputDevice->isKeyDown(KC_ESCAPE);
	}
protected:
	bool mRefreshDown;       // Whether or not the refresh button is down last frame
	Refresher* mRefresher;
	
};

class OpenGUIViewer : public ExampleApplication, public Refresher
{
protected:
	OpenGUI::OgreRenderer* mGuiRenderer;
	OpenGUI::System* mGuiSystem;
	OpenGUI::OgreResourceProvider* mGuiProvider;
	OpenGUI::OgreViewport* mGuiViewport;
	OpenGUI::Screen* mGuiScreen;
public:
    OpenGUIViewer()
    {
    }

    ~OpenGUIViewer() 
    {
    }
	void refreshScreen() 
	{
		//Unload the previous screen
		OpenGUI::ScreenManager::getSingleton().destroyScreen(mGuiScreen);
		mGuiSystem->unloadPlugin("Amethyst"); //Have to unload plugin - workaround
		//Reload the screen and set it as the active one.
		OpenGUI::XMLParser::getSingleton().LoadFromFile(GUI_SCREEN_FILE_NAME);
		
		mGuiScreen = OpenGUI::ScreenManager::getSingleton().getScreen(GUI_SCREEN_NAME);
		mGuiScreen->setViewport(mGuiViewport);
	}
protected:
    void createScene(void)
    {
		mGuiRenderer = new OpenGUI::OgreRenderer(mRoot, mRoot->getRenderSystem());
		mGuiProvider = new OpenGUI::OgreResourceProvider();
		mGuiSystem = new OpenGUI::System(mGuiRenderer, mGuiProvider);
		OpenGUI::XMLParser::getSingleton().LoadFromFile(GUI_SCREEN_FILE_NAME);
		mGuiViewport = new OpenGUI::OgreViewport(mWindow->getViewport(0));
		//Screen has been created already when the xml was loaded, we just need to get it.
		mGuiScreen = OpenGUI::ScreenManager::getSingleton().getScreen(GUI_SCREEN_NAME);
		mGuiScreen->setViewport(mGuiViewport);
	}

	void createFrameListener(void)
	{
		// Create the FrameListener
		mFrameListener = new RefresherFrameListener(mWindow, mCamera, mSceneMgr, this);
		mRoot->addFrameListener(mFrameListener);
		mFrameListener->showDebugOverlay(false);
	}
};

#if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"

INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
{
    // Create application object
    OpenGUIViewer app;

    try {
        app.go();
	} catch( OpenGUI::Exception& e ) {
#if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
		MessageBox( NULL, e.getFullMessage().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
        fprintf(stderr, "An exception has occured: %s\n",
                e.getFullDescription().c_str());
#endif
    } catch( Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
        std::cerr << "An exception has occured: " << e.getFullDescription();
#endif
    }

    return 0;
}

Some notes :
- OpenGUI knows to search for its resources in the Ogre resource dir if you initialized it with the OgreResourceProvider
- As of the time of this article (OpenGUI 0.8), plugins can not be loaded twice. Amethyst is a plugin that comes with OpenGUI and provides basic high level widgets (buttons, labels etc). The XML will usually <Include> it, so I unload it in refreshScreen(). Perhaps multiple load will just ignore the load in the future rather than crash, then this line will not be neccesary. But, for now it means that the XML you give it must include amethyst.
- To build this sample, you need to include the opengui, ogre and opengui ogre renderer include libraries, and link with OgreMain.lib, OpenGUI.lib and Renderer_Ogre.lib.
- This sample does not destroy the environment, it is just a trivial screen viewer. Feel free to edit this page and add OpenGUI environment destruction.
- As you can see in the code, the application expects to see a screen named "DesignScreen" in a file called "OpenGuiTest.xml". You can change this if you want. Here is an example of such an XML :

<?xml version="1.0" ?>
<OpenGUI>
	<Plugin File="Amethyst"/>

	<Font Name="solo5" File="solo5.ttf" />

	<Screen Name="DesignScreen" Size="(320x240)" UPI="(96x96)" AutoUpdating="True" AutoTiming="True" >
		<Widget Name="TheButton" BaseName="Button" BaseLibrary="Amethyst">
			<Property ValueName="Font" ValueType="FONT" ValueData="solo5 @ 36" />
			<Property ValueName="Text" ValueType="STRING" ValueData="OpenGUI" />
			<Property ValueName="FontColor" ValueType="COLOR" ValueData="1.0:1.0:1.0:1.0" />
		</Widget>
	</Screen>
</OpenGUI>

It is a very basic XML, the OpenGUI SDK contains documentation+samples on how to do pretty stuff with it.
All in all, OpenGUI is a promising GUI library, and is pretty easy to integrate into OGRE. I hope this how-to helped you a bit.

Personal tools
administration