In this article we are going to integrate CEGUI into the Practical Application codebase.

CEGUI


This version of the code will also say goodbye to the VC71 projects and hello to the VC8 (Visual C++ 2005) projects, since that's what I work in now (and have done for some time now). Those using VC71 probably have enough experience to be able to cobble together the projects to build the code — it's fairly straightforward. This version of the code also targets Ogre 1.4.x (Eihort) — again, if you are running Dagon (1.2.x) you can probably figure out the couple of minor changes needed to make it run; they are primarily the way that the message pump is exercised, as well as some OIS changes (since the Eihort samples use the latest OIS, and that's what comes with the SDK). As always, this code was built and tested against the Ogre SDK (1.4.1 in this case).

CEGUI is a 2D UI rendering library that is rendering-engine agnostic — it has direct support for OpenGL and Irrlicht as well as Ogre. It is a library that is heavily XML-based in terms of its script file formats. While you can certainly define all of your UI in code, it is simpler to define it in XML files that CEGUI loads and parses at runtime. CEGUI comes with several samples, including the media needed to run those samples and the XML script files needed to define the look and feel of the UI elements used in the samples. These provided schemes, look-and-feel, and layout files are good to get you started, but chances are you will want to define your own UI widget look and feel for your own application. However, doing that is beyond the scope of this article; see the CEGUI site for more.

Rendering The UI


CEGUI renders its UI elements to mesh quads that are drawn to the display in "screen space". This means that the mesh objects that make up the UI elements on your screen are drawn without any view or projection transformations. This is the standard way that any 2D UI system operates. CEGUI interacts with Ogre via the "OgreGUIRenderer", a class that is provided in the Ogre "Samples" codebase but exists in the "CEGUI" namespace. The OgreGUIRenderer simply takes draw commands from CEGUI and translates them into Ogre Mesh and texture data that Ogre can then display, usually in the "Overlay" render queue (RENDER_QUEUE_OVERLAY). This ensures that the UI is drawn on top of everything else in your scene. In code, you do not need to deal with the OgreGUIRenderer class other than to make an instance of one and pass it to CEGUI, which then takes it from there.

Input and CEGUI


You have to provide CEGUI with all input events — it does not have any inherent input processing of its own, depending instead on input data provided by your application. This has a few nice benefits. For one, you don't have to worry about the UI library fighting with your application for access to the input data. Furthermore, you can cut CEGUI entirely out of the "input loop" at your discretion simply by not providing it with any input data. You also are not tied to any particular input library or API; you can use whatever you like: OIS, SDL, DirectInput, Win32 or XWindows input message data, it's entirely up to you. In this article we are using OIS to gather the input events and forward those to CEGUI.

CEGUI Data Files


As mentioned, you are perfectly able to define your UI layouts entirely in code, but the method most easily iterated is via the several XML files CEGUI can consume as input data. These files define the "scheme", "look-n-feel", "layout", "imagesets" and fonts that CEGUI displays.

  • Scheme. Definition of the different UI elements that are valid in a particular "scheme", for example buttons, listboxes, and so on. Found in .scheme files.
  • Look-And-Feel. Definition of the way that each UI element is presented on the display, including its behaviors and the textures used to render it. Found in .looknfeel files.
  • Layout. Defines the position, size, parenting hierarchy and other properties used to display actual UI elements in a single unit: the UI "sheet". Found in .layout files.
  • Imageset. Defines the textures used in a scheme, and the UV coordinates that are actually mapped to UI element quads on your screen. Found in .imageset files.
  • Font. Should be obvious; CEGUI needs to know where to find the fonts you intend to use for your text, including the glyph definitions and the font texture to use. Found in .font files.


In the gui.zip resource data file accompanying the source for this article, you will find many examples of all of these types of files. Look through each type of file and see what they contain — they are all just text XML files. Their format and contents should be self-evident once you've examined them for a bit — if not, the CEGUI site has documentation on them all. This article uses the "TaharezLookSkin" scheme. (The name "Taharez" comes from the screen name of the person who created the scheme, look-and-feel, texture and imageset for the scheme).

Falagard Skinning System


There is also another part of CEGUI that works behind the scenes, but starting with CEGUI 0.5.x (the version used in this article), is core to its operation. The "Falagard" skinning system was devised as a way to remove the need to create a separate code module (DLL) that was used actually to assemble and render each different scheme and look-and-feel. As you might expect (if you are a regular in the Ogre forums) the person (at least mostly) responsible for its creation was Falagard (unless my information is incorrect, of course). This method of UI skinning is a generalized, data-driven way to render the UI elements without having to author special code to do it. It relies on all of that data found in the look-and-feel and scheme files for its operation — verbosity of data is one of the prices you pay for flexibility. ;)

The Code


So, enough introduction, let's look at the code. If you have followed the series this far, you are familiar with the code that produces a blank Ogre render window and waits for you to press ESC to quit. In this version of the code, the blank window is replaced by a layout that we used in our proof-of-concept phase as a sort of minimalist main menu page. It contains three buttons, only one of which does anything. What that one button (the "Quit" button) does is allow you, in addition to the ESC key, the ability to click that button to exit the app. While that may sound underwhelming, it's purpose is served in that it demonstrates the entire data pathway needed to get input events into CEGUI (in this case, mouse click) through the actual invocation of your code in response to that click. From there it should be fairly obvious how you would go about hooking CEGUI actions into your own code. Note that this is all in C++ — if you are interested in script hooks into CEGUI (such as for Lua or other scripting engines) you are encouraged to visit the CEGUI site for more on how to do that.

The Data


At the risk of making myself a liar right off the bat, we first should look at the vital CEGUI data file used in this article: the layout file. There is more than one visual CEGUI layout editing tool available, and each is in a different state of completeness and maintenance, so you might find it simplest just to edit the XML .layout files by hand — I did. YMMV.

In the file gui.zip in the resource/ directory under Debug in the source distribution, you will find a file called "katana.layout". Here is the contents of that file in its entirety:

<?xml version="1.0" ?>
<GUILayout>
	<Window Type="TaharezLook/FrameWindow" Name="Main">
            <Property Name="UnifiedAreaRect" Value="{{0.0,0},{0.0,0},{1.0,0},{1.0,0}}" />
            <Property Name="FrameEnabled" Value="false" />
            <Property Name="TitlebarEnabled" Value="false" />
            <Property Name="CloseButtonEnabled" Value="False" />

		<Window Type="TaharezLook/Button" Name="cmdQuit">
			<Property Name="Text" Value="Quit" />
       		<Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.7,0},{0.6,0},{0.77,0}}" />
		</Window>
		<Window Type="TaharezLook/Button" Name="cmdOptions">
       		<Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.6,0},{0.6,0},{0.67,0}}" />
			<Property Name="Text" Value="Options" />
		</Window>
		<Window Type="TaharezLook/Button" Name="cmdInstantAction">
       		<Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.5,0},{0.6,0},{0.57,0}}" />
			<Property Name="Text" Value="Instant Action" />
		</Window>
	</Window>
</GUILayout>


The first thing you notice (probably), at least when your eyes stop spinning, are those weird sets of numbers in the braces. As of CEGUI 0.5.x, the only way to define UI element dimensions is with the "Unified Dimension" (UDim) system. In this layout file, we are using UnifiedAreaRect, which is a series of number pairs that define the left, top, right and bottom positions of your UI element. The pairs of numbers are set up to allow you to define your dimensions in either relative or absolute terms, in the space of the containing element. For example, the rect definition

{{0.4,0},{0.5,0},{0.6,0},{0.57,0}}

tells CEGUI that, in the "space" of the the parent element (in this case, the FrameWindow which makes up the top-level container for the entire GUI sheet), we want to place our element (in the case of this set of numbers that I stole from the layout, the "Instant Action" button) 40% (0.4) from the left of the FrameWindow, and 50% (0.5) from the top (using the upper-left corner of the button as its origin). The button's width will be 20% (0.2, or "0.6 - 0.4") of the parent's width and its height will be 7% of the parent's height (0.07, or "0.57 - 0.5"). So, what are those other zeros in there? If we had wanted to define the button's size in "absolute" terms, we would have used those numbers instead (and inserted actual pixel values instead of relative coordinates). You can also combine relative and absolute values in any way you like; I don't recall the order of precedence if you specify both for a particular dimension — it's been a while since I put together this layout, and anyone who knows for sure can feel free to edit this article. ;) BTW, anyone who has done any web page layout should be VERY familiar with this concept of relative and absolute dimensions — it's the same thing.

The first lines in the layout tell CEGUI what we want to call our top-level window ("Main"), and that we want it to take up the whole screen — (0,0) to (1,1) in relative terms. We do not want to see its title bar (which is on by default), it's "X" close button (ditto) or its frame (ditto again). We place three buttons on the screen, in the center, organized top to bottom (but not in the order they appear in the file — when you run the app they will display "Instant Action", then "Options", then "Quit" from top to bottom). The buttons' "Name" parameter is important — this is how we will hook the button actions (mouse click for example) into code, as we will see shortly.

And Then, Now The Code


I will highlight now the changes made to the code to integrate CEGUI into the application. First, in main.cpp, some additional headers:

// needed to be able to create the CEGUI renderer interface
#include "OgreCEGUIRenderer.h"

// CEGUI includes
#include "CEGUISystem.h"
#include "CEGUIInputEvent.h"
#include "CEGUIWindow.h"
#include "CEGUIWindowManager.h"
#include "CEGUISchemeManager.h"
#include "CEGUIFontManager.h"
#include "elements/CEGUIFrameWindow.h"


CEGUI 0.7.1 (really 0.7.0) introduced several changes that, in my opinon, clean up the look of the code quite a bit. Even if you don't agree, there are still some major changes that need to be taken into account if you are using 0.7.0+. Below is the include section that must be used if you are using CEGUI 0.7.1:

#include "RendererModules/Ogre/CEGUIOgreRenderer.h"

// CEGUI includes
#include "CEGUISystem.h"
#include "CEGUIInputEvent.h"
#include "CEGUIWindow.h"
#include "CEGUIWindowManager.h"
#include "CEGUISchemeManager.h"
#include "CEGUIFontManager.h"
#include "elements/CEGUIFrameWindow.h"


In this case, the first include has been changed because the OgreRenderer is no longer an automatic part of the Ogre release but has been left in the CEGUI code with a name change to match the pattern of the other renderers included in that package. Now, on with the show. I will highlight changes that must be made to use 0.7.1 as this tutorial continues along. I happen to have my paths set up for CEGUI much like I have for Ogre. That is, the include directory for CEGUI is part of the other includes path. You may have set things up differently. In that case, you need to alter the top #include to suit your setup.

We will be creating an instance of the GUI renderer, so we need to reference its header. You'll find that header in the SDK or Ogre source under Samples/include (which was added to the project's Additional Include Directories paths). The CEGUI headers can be found in the SDK under include/CEGUI (which we also added to the include paths). For those used to seeing "CEGUI/CEGUISystem.h", that way was finally abandoned in CEGUI — all of the CEGUI files now have that directory prefix removed. If you are having trouble compiling as a result, feel free to add both "include/CEGUI" and "include" (where "include" contains the "CEGUI" subdirectory). I probably did not need to include the "elements/CEGUIFrameWindow.h" file above; it's probably lingering from an old version of source that was cut-and-pasted. ;) It's harmless.

Initializing CEGUI

main.cpp

// with a scene manager and window, we can create a the GUI renderer
	CEGUI::OgreCEGUIRenderer* pGUIRenderer = new CEGUI::OgreCEGUIRenderer(
		window,					// the render window created earlier; CEGUI renders to this
		Ogre::RENDER_QUEUE_OVERLAY,		// CEGUI should render in this render queue
		false,					// put everything in the above render queue first, not last
		3000,					// this is actually unnecessary now in CEGUI -- max quads for the UI
		sceneMgr				// use this scene manager to manage the UI
	);

	// create the root CEGUI class
	CEGUI::System* pSystem = new CEGUI::System(pGUIRenderer);

	// tell us a lot about what is going on (see CEGUI.log in the working directory)
	CEGUI::Logger::getSingleton().setLoggingLevel(CEGUI::Informative);

	// use this CEGUI scheme definition (see CEGUI docs for more)
	CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLookSkin.scheme", (CEGUI::utf8*)"GUI");

	// show the CEGUI mouse cursor (defined in the look-n-feel)
	pSystem->setDefaultMouseCursor((CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");

	// use this font for text in the UI
	CEGUI::FontManager::getSingleton().createFont("Tahoma-8.font", (CEGUI::utf8*)"GUI");
	pSystem->setDefaultFont((CEGUI::utf8*)"Tahoma-8");

	// load a layout from the XML layout file (you'll find this in resources/gui.zip), and 
	// put it in the GUI resource group
	CEGUI::Window* pLayout = CEGUI::WindowManager::getSingleton().loadWindowLayout("katana.layout", "", "GUI");

	// you need to tell CEGUI which layout to display. You can call this at any time to change the layout to
	// another loaded layout (i.e. moving from screen to screen or to load your HUD layout). Note that this takes
	// a CEGUI::Window instance -- you can use anything (any widget) that serves as a root window.
	pSystem->setGUISheet(pLayout);


Here, too, there are several changes if you are using CEGUI 0.7.0+. The way that CEGUI is initialized has changed and is much simpler to read. Below is the CEGUI 0.7.1 code for this section.

// with a scene manager and window, we can create a the GUI renderer

	// new way to instantiate a CEGUIOgreRenderer (Ogre 1.7)
	Ogre::RenderTarget *mRenderTarget = window;
	CEGUI::OgreRenderer* pGUIRenderer = &CEGUI::OgreRenderer::bootstrapSystem(*mRenderTarget);

	// create the root CEGUI class
	CEGUI::System* pSystem = CEGUI::System::getSingletonPtr();

	// tell us a lot about what is going on (see CEGUI.log in the working directory)
	CEGUI::Logger::getSingleton().setLoggingLevel(CEGUI::Informative);

	// use this CEGUI scheme definition (see CEGUI docs for more)
	CEGUI::SchemeManager::getSingleton().create((CEGUI::utf8*)"TaharezLookSkin.scheme", (CEGUI::utf8*)"GUI");

	// show the CEGUI mouse cursor (defined in the look-n-feel)
	pSystem->setDefaultMouseCursor((CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");

	// use this font for text in the UI
	CEGUI::FontManager::getSingleton().create("Tahoma-8.font", (CEGUI::utf8*)"GUI");
	pSystem->setDefaultFont((CEGUI::utf8*)"Tahoma-8");

	// load a layout from the XML layout file (you'll find this in resources/gui.zip), and 
	// put it in the GUI resource group
	CEGUI::Window* pLayout = CEGUI::WindowManager::getSingleton().loadWindowLayout("katana.layout", "", "GUI");

	// you need to tell CEGUI which layout to display. You can call this at any time to change the layout to
	// another loaded layout (i.e. moving from screen to screen or to load your HUD layout). Note that this takes
	// a CEGUI::Window instance -- you can use anything (any widget) that serves as a root window.
	pSystem->setGUISheet(pLayout);


The important changes here are the new way to instantiate the CEGUI OgreRenderer. Note the class name has changed from CEGUI::OgreCEGUIRenderer to CEGUI::OgreRenderer. In addition the large initialization function call has been reduced to a nice neat single (or no) parameter function, thus handling a number of initialization features on its own based on the renderer you pass to it. At any rate, the initialization section is below:

Ogre::RenderTarget *mRenderTarget = window;
	CEGUI::OgreRenderer* pGUIRenderer = &CEGUI::OgreRenderer::bootstrapSystem(*mRenderTarget);

	// create the root CEGUI class
	CEGUI::System* pSystem = CEGUI::System::getSingletonPtr();


We need a pointer to the Ogre RendererTarget rather than an Ogre window. It is through this that the bootstrapSystem function will extrapolate all of the information that you used to have to pass in the old instantiation method.

We also still want a pointer to the CEGUI System and that is what the final line above does for us.

This code is liberally commented so I won't repeat much here. Note that we use the Ogre render window that was created in main.cpp ("window") as well as the scene manager ("sceneMgr") so you will find this code in main.cpp following the creation and setup of those objects.

Input Support For CEGUI


We needed to change the signature of the InputHandler class to take an additional parameter: a pointer to the instance of CEGUI::System we created in main.cpp. This is because now the input handler is responsible for pushing input events into CEGUI:

input.cpp

// MouseListener
bool InputHandler::mouseMoved(const OIS::MouseEvent &evt) {
	m_pSystem->injectMouseWheelChange(evt.state.Z.rel);
	return m_pSystem->injectMouseMove(evt.state.X.rel, evt.state.Y.rel);
}

bool InputHandler::mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID btn) {
	CEGUI::MouseButton button = CEGUI::NoButton;

	if (btn == OIS::MB_Left)
		button = CEGUI::LeftButton;
	
	if (btn == OIS::MB_Middle)
		button = CEGUI::MiddleButton;
	
	if (btn == OIS::MB_Right)
		button = CEGUI::RightButton;

	return m_pSystem->injectMouseButtonDown(button);
}

bool InputHandler::mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID btn) {
	CEGUI::MouseButton button = CEGUI::NoButton;

	if (btn == OIS::MB_Left)
		button = CEGUI::LeftButton;
	
	if (btn == OIS::MB_Middle)
		button = CEGUI::MiddleButton;
	
	if (btn == OIS::MB_Right)
		button = CEGUI::RightButton;
	
	return m_pSystem->injectMouseButtonUp(button);
}

		
// KeyListener
bool InputHandler::keyPressed(const OIS::KeyEvent &evt) {
	unsigned int ch = evt.text;

	m_pSystem->injectKeyDown(evt.key);
	return m_pSystem->injectChar(ch);
}

bool InputHandler::keyReleased(const OIS::KeyEvent &evt) {
	if (evt.key == OIS::KC_ESCAPE)
		m_simulation->requestStateChange(SHUTDOWN);

	return m_pSystem->injectKeyUp(evt.key);
}


Note: returning the results of injectChar and injectKeyUp can result in keystrokes (to say, an edit box) being lost when typing quickly. You may want to always return true instead, so that all buffered keystrokes will be processed.

It should be fairly evident how input events make it into CEGUI from this code — the "inject***" calls in the code above (which are methods on CEGUI::System). You can make these calls from anywhere that you have access to the input events; I do it in the input handler class because it's convenient and the rest of the application really doesn't need to worry about it or even know about it — it will get notified of UI actions through a different data path.

main.cpp

// since the input handler deals with pushing input to CEGUI, we need to give it a pointer
	// to the CEGUI System instance to use
	InputHandler *handler = new InputHandler(pSystem, sim, hWnd);

	// put us into our "main menu" state
	sim->requestStateChange(GUI);


We also now change to the "GUI" state instead of "SIMULATION" as we did in the previous article — in a normal app you typically would go first into a "main menu" state instead of going directly into the game, so this state change follows that pattern. You would also deal with creating a class to deal with UI actions in your state manager; fro simplicity (and since we are not changing states at this time) we just do it in main.cpp:

// make an instance of our GUI sheet handler class
	MainMenuDlg* pDlg = new MainMenuDlg(pSystem, pLayout, sim);


This action handler class is new to this article; you'll find its declaration and definition in MainMenuDlg.h and .cpp:

MainMenuDlg.h

#pragma once

#include "CEGUIWindow.h"

namespace CEGUI
{
	class System;
	class Window;
}

class Simulation;

class MainMenuDlg
{
public:
	MainMenuDlg(CEGUI::System* pSystem, CEGUI::Window* pSheet, Simulation* pSimulation);
	~MainMenuDlg();

	// CEGUI event handlers. You can name these whatever you like, so long as they have the proper 
	// signature: bool <method name>(const CEGUI::EventArgs &args)
	bool Quit_OnClick(const CEGUI::EventArgs &args);
	bool Options_OnClick(const CEGUI::EventArgs &args);
	bool Launch_OnClick(const CEGUI::EventArgs &args);

private:
	CEGUI::System* m_pSystem;	// pointer to the CEGUI System instance
	CEGUI::Window* m_pWindow;	// pointer to the layout sheet window
	Simulation* m_pSimulation;	// pointer to the Simulation controller 
};


MainMenuDlg.cpp

#include "MainMenuDlg.h"
#include "Simulation.h"
#include "CEGUISystem.h"
#include "CEGUIWindow.h"
#include "CEGUIWindowManager.h"
#include "elements/CEGUIPushButton.h"

MainMenuDlg::MainMenuDlg(CEGUI::System *pSystem, CEGUI::Window *pSheet, Simulation *pSimulation)
{
	m_pSystem = pSystem;
	m_pWindow = pSheet;
	m_pSimulation = pSimulation;

	// hook up the event handlers to the window elements
	CEGUI::PushButton* pQuitButton = (CEGUI::PushButton *)CEGUI::WindowManager::getSingleton().getWindow("cmdQuit");
	pQuitButton->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&MainMenuDlg::Quit_OnClick, this));

	CEGUI::PushButton* pOptionsButton = (CEGUI::PushButton *)CEGUI::WindowManager::getSingleton().getWindow("cmdOptions");
	pOptionsButton->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&MainMenuDlg::Options_OnClick, this));

	CEGUI::PushButton* pLaunchButton = (CEGUI::PushButton *)CEGUI::WindowManager::getSingleton().getWindow("cmdInstantAction");
	pLaunchButton->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&MainMenuDlg::Launch_OnClick, this));
}

MainMenuDlg::~MainMenuDlg()
{
}

bool MainMenuDlg::Quit_OnClick(const CEGUI::EventArgs &args)
{
	m_pSimulation->requestStateChange(SHUTDOWN);
	return true;
}

bool MainMenuDlg::Launch_OnClick(const CEGUI::EventArgs &args)
{
	return true;
}

bool MainMenuDlg::Options_OnClick(const CEGUI::EventArgs &args)
{
	return true;
}


The two primary things to observe are (a) how the action handler methods are hooked up to CEGUI events, and (b) that we handle the "Quit" button click by telling the application to shut down (same as we did in the ESC keypress handler). If you are feeling frisky, you can make your own layouts and add code to the other stubbed handlers (Launch_OnClick and Options_OnClick) to push different GUI sheets onto the display (using the "loadWindowLayout" call as above in main.cpp).

Conclusion


There really is not that much more to it than that — how you set up your UI action handlers, and how you feed input into CEGUI, is entirely up to you. You can use the code here, or devise your own, but the basics don't change. And there really is not much more to say on getting started with CEGUI and Ogre — the rest revolves around making layouts (and maybe even different schemes and looks-and-feels), as well as creating the hooks from CEGUI element actions into your code.

Download The Code


As mentioned, I migrated the code and projects to Ogre 1.4.x (Eihort) and also the VC8 project file formats. You can download the code and it should build right out of the box if you have the Ogre 1.4.x SDK installed (and are using VC8, of course). Note that the project copies the executable to the $(OGRE_HOME)/bin/Debug folder — you may need to set your Working Directory in Visual Studio to reflect that, and you certainly will need to copy the gui.zip file from the Debug folder in the PracticalApp source tree to a "resource" folder in $(OGRE_HOME)/bin/Debug (you may need to create this folder). You may also be able to run it from the Debug folder in the PracticalApp source tree if your PATH contains $(OGRE_HOME)/bin/Debug.

Note as well that I only set up the projects in the Debug configurations — it is expected that you would use this code in a different project/solution of your own, so if you instead use the PracticalApp solution as your starting point and intend to build Release configs, you probably will need to set up the project settings properly for that config.

Enjoy!

CEGUI 0.7.1 note


The above linked code in the Download The Code section is not for 0.7.1. I do not have a full source and gui.zip package compiled together for you. The changes outlined earlier in this tutorial should suffice to get you going. There are some other changes with CEGUI 0.7.0+ that you should be aware of. Without getting out of scope for this tutorial, suffice it to say that the old tag <WindowSet> is now <WindowRendererSet> and the CEGUIFalagardBase is now CEGUIFalagardWRBase. The .scheme files had to be changed to reflect this or you will get many crashes and not necessarily easily see why. Here is the new gui.zip file you can use with this tutorial and CEGUI 0.7.1.

CEGUI 0.8.3 note

There are some not easy to find changes for CEGUI 8.3. The source code and a Makefile for a Linux distro can be downloaded from

 Plugin disabled

Plugin attach cannot be executed.
. I removed any unnecessary file from gui.zip, since most xml files would not work with this version of CEGUI.


Prev <<< Practical Application - Let's Get StartedPractical Application - I Haven't Decided What's Next >>> Next


Alias: Practical_Application_-_Something_With_A_Bit_More_Meat

<HR>
Creative Commons Copyright -- Some rights reserved.


THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.

BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.

1. Definitions

  • "Collective Work" means a work, such as a periodical issue, anthology or encyclopedia, in which the Work in its entirety in unmodified form, along with a number of other contributions, constituting separate and independent works in themselves, are assembled into a collective whole. A work that constitutes a Collective Work will not be considered a Derivative Work (as defined below) for the purposes of this License.
  • "Derivative Work" means a work based upon the Work or upon the Work and other pre-existing works, such as a translation, musical arrangement, dramatization, fictionalization, motion picture version, sound recording, art reproduction, abridgment, condensation, or any other form in which the Work may be recast, transformed, or adapted, except that a work that constitutes a Collective Work will not be considered a Derivative Work for the purpose of this License. For the avoidance of doubt, where the Work is a musical composition or sound recording, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered a Derivative Work for the purpose of this License.
  • "Licensor" means the individual or entity that offers the Work under the terms of this License.
  • "Original Author" means the individual or entity who created the Work.
  • "Work" means the copyrightable work of authorship offered under the terms of this License.
  • "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
  • "License Elements" means the following high-level license attributes as selected by Licensor and indicated in the title of this License: Attribution, ShareAlike.

2. Fair Use Rights

Nothing in this license is intended to reduce, limit, or restrict any rights arising from fair use, first sale or other limitations on the exclusive rights of the copyright owner under copyright law or other applicable laws.

3. License Grant

Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:

  • to reproduce the Work, to incorporate the Work into one or more Collective Works, and to reproduce the Work as incorporated in the Collective Works;
  • to create and reproduce Derivative Works;
  • to distribute copies or phonorecords of, display publicly, perform publicly, and perform publicly by means of a digital audio transmission the Work including as incorporated in Collective Works;
  • to distribute copies or phonorecords of, display publicly, perform publicly, and perform publicly by means of a digital audio transmission Derivative Works.
  • For the avoidance of doubt, where the work is a musical composition:
    • Performance Royalties Under Blanket Licenses. Licensor waives the exclusive right to collect, whether individually or via a performance rights society (e.g. ASCAP, BMI, SESAC), royalties for the public performance or public digital performance (e.g. webcast) of the Work.
    • Mechanical Rights and Statutory Royalties. Licensor waives the exclusive right to collect, whether individually or via a music rights society or designated agent (e.g. Harry Fox Agency), royalties for any phonorecord You create from the Work ("cover version") and distribute, subject to the compulsory license created by 17 USC Section 115 of the US Copyright Act (or the equivalent in other jurisdictions).
    • Webcasting Rights and Statutory Royalties. For the avoidance of doubt, where the Work is a sound recording, Licensor waives the exclusive right to collect, whether individually or via a performance-rights society (e.g. SoundExchange), royalties for the public digital performance (e.g. webcast) of the Work, subject to the compulsory license created by 17 USC Section 114 of the US Copyright Act (or the equivalent in other jurisdictions).


The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. All rights not expressly granted by Licensor are hereby reserved.

4. Restrictions

The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:

  • You may distribute, publicly display, publicly perform, or publicly digitally perform the Work only under the terms of this License, and You must include a copy of, or the Uniform Resource Identifier for, this License with every copy or phonorecord of the Work You distribute, publicly display, publicly perform, or publicly digitally perform. You may not offer or impose any terms on the Work that alter or restrict the terms of this License or the recipients' exercise of the rights granted hereunder. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties. You may not distribute, publicly display, publicly perform, or publicly digitally perform the Work with any technological measures that control access or use of the Work in a manner inconsistent with the terms of this License Agreement. The above applies to the Work as incorporated in a Collective Work, but this does not require the Collective Work apart from the Work itself to be made subject to the terms of this License. If You create a Collective Work, upon notice from any Licensor You must, to the extent practicable, remove from the Collective Work any credit as required by clause 4(c), as requested. If You create a Derivative Work, upon notice from any Licensor You must, to the extent practicable, remove from the Derivative Work any credit as required by clause 4(c), as requested.
  • You may distribute, publicly display, publicly perform, or publicly digitally perform a Derivative Work only under the terms of this License, a later version of this License with the same License Elements as this License, or a Creative Commons iCommons license that contains the same License Elements as this License (e.g. Attribution-ShareAlike 2.5 Japan). You must include a copy of, or the Uniform Resource Identifier for, this License or other license specified in the previous sentence with every copy or phonorecord of each Derivative Work You distribute, publicly display, publicly perform, or publicly digitally perform. You may not offer or impose any terms on the Derivative Works that alter or restrict the terms of this License or the recipients' exercise of the rights granted hereunder, and You must keep intact all notices that refer to this License and to the disclaimer of warranties. You may not distribute, publicly display, publicly perform, or publicly digitally perform the Derivative Work with any technological measures that control access or use of the Work in a manner inconsistent with the terms of this License Agreement. The above applies to the Derivative Work as incorporated in a Collective Work, but this does not require the Collective Work apart from the Derivative Work itself to be made subject to the terms of this License.
  • If you distribute, publicly display, publicly perform, or publicly digitally perform the Work or any Derivative Works or Collective Works, You must keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or (ii) if the Original Author and/or Licensor designate another party or parties (e.g. a sponsor institute, publishing entity, journal) for attribution in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; the title of the Work if supplied; to the extent reasonably practicable, the Uniform Resource Identifier, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and in the case of a Derivative Work, a credit identifying the use of the Work in the Derivative Work (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). Such credit may be implemented in any reasonable manner; provided, however, that in the case of a Derivative Work or Collective Work, at a minimum such credit will appear where any other comparable authorship credit appears and in a manner at least as prominent as such other comparable authorship credit.

5. Representations, Warranties and Disclaimer

UNLESS OTHERWISE AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE MATERIALS, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.

6. Limitation on Liability.

EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

7. Termination

  • This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Derivative Works or Collective Works from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
  • Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.

8. Miscellaneous

  • Each time You distribute or publicly digitally perform the Work or a Collective Work, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
  • Each time You distribute or publicly digitally perform a Derivative Work, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.
  • If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
  • No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.
  • This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.