Tutorial Básico 7 CEGUI y Ogre


external image dl1773

Introducción del Tutorial


En este tutorial exploraremos el uso de CEGUI con Ogre. Cuando termine el tutorial deberías ser capaz de añadir funcionalidad básica con CEGUI a tu aplicacion. NOTA: Este tutorial no intenta enseñarte completamente CEGUI. Este tutorial es un comienzo. Todas las demas cuestiones sobre CEGUI y la ayuda debería ser pedida en su página web.

Tutoriales más profundos y mejores sobre CEGUI se encuentran en la documentación de doxygen con la distribución de CEGUI o aquí en línea.

external image help.gifLos problemas que encuentres mientras trabajes en este tutorial deberías consultarlos en los Foros de Ayuda.

Prerrequisitos

  • Este tutorial asume que tienes conocimientos sobre programación en C++ y eres capaz de compilar e instalar una aplicación de Ogre.
  • Este tutorial tambien asume que has creado un proyecto usando el Tutorial Framework Ogre Wiki, manualmente, usando CMake o el AppWizard de Ogre - mirar Creando una aplicación para más instrucciones.
  • Este tutorial se compila sobre la versión anterior de los tutoriales básicos, así que se asume que has trabajado con ellos.

Cuando mires el tutorial deberías ir lentamente añadiendo código a tu proyecto y mirando los resultados. Puedes ver el código fuente para ver el estado final del tutorial aquí. Si tienes problemas con el código, deberías comparar tu fuente del proyecto al resultado final.

Comenzando


El Código Inicial


Modifica la cabecera de la clase Basic Tutorial 7 para que se parezca a esto:

cabecera BasicTutorial7
#include <CEGUI/CEGUI.h>
#include <CEGUI/RendererModules/Ogre/CEGUIOgreRenderer.h>
 
class BasicTutorial7 : public BaseApplication
{
public:
 BasicTutorial7(void);
 virtual ~BasicTutorial7(void);
 
protected:
 CEGUI::OgreRenderer* mRenderer;
 
 virtual void createScene(void);
 
 virtual void createFrameListener(void);
 
 // Ogre::FrameListener
 virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt);
 
 // OIS::KeyListener
 virtual bool keyPressed( const OIS::KeyEvent &arg );
 virtual bool keyReleased( const OIS::KeyEvent &arg );
 // OIS::MouseListener
 virtual bool mouseMoved( const OIS::MouseEvent &arg );
 virtual bool mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id );
 virtual bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id );
 
 bool quit(const CEGUI::EventArgs &e);
};
Asegúrate que tu archivo de implementación del Tutorial Básico 7 se parece a esto:

Implementacion BasicTutorial7

// ------------------------------------------------------------------------------
BasicTutorial7::BasicTutorial7(void)
{
}
// -------------------------------------------------------------------------------------
BasicTutorial7::~BasicTutorial7(void)
{
}
// ---------------------------------------------------------------------------------
void BasicTutorial7::createScene(void)
{
}
// -------------------------------------------------------------------------------------
void BasicTutorial7::createFrameListener(void)
{
 BaseApplication::createFrameListener();
}
// ---------------------------------------------------------------------------------------
bool BasicTutorial7::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
 return BaseApplication::frameRenderingQueued(evt);
}
// -------------------------------------------------------------------------------------
bool BasicTutorial7::keyPressed( const OIS::KeyEvent &arg )
{
 return BaseApplication::keyPressed(arg);
}
// ------------------------------------------------------------------------------------------
bool BasicTutorial7::keyReleased( const OIS::KeyEvent &arg )
{
 return BaseApplication::keyReleased(arg);
}
// -------------------------------------------------------------------------------------
bool BasicTutorial7::mouseMoved( const OIS::MouseEvent &arg )
{
 return BaseApplication::mouseMoved(arg);
}
// --------------------------------------------------------------------------------------
bool BasicTutorial7::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
 return BaseApplication::mousePressed(arg, id);
}
// -------------------------------------------------------------------------------------
bool BasicTutorial7::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
 return BaseApplication::mouseReleased(arg, id);
}
// -----------------------------------------------------------------------------------------
bool BasicTutorial7::quit(const CEGUI::EventArgs &e)
{
 return true;
}

Ajustes de Proyecto


Necesitas CEGUI, con el CEGUI Ogre renderizado compilado contra Ogre 1.7 - ej: la versión de Ogre que estas usando.

Mirar Construir CEGUI para más instrucciones.

Entonces necesitas añadir la posición de las cabeceras de CEGUI a los directorios include de tu proyecto.
Este código asume que has preparado un CEGUI SDK con la siguiente configuración de directorio:

external image dl1866&display

Después de compilar CEGUI puedes copiar estos archivos para hacer un SDK.
Esto es por completo opcional, sin embargo las instrucciones de aquí, estan basadas en este supuesto.

Si no quieres usar las cabeceras CEGUI en un directorio llamado "CEGUI", solo elimina "CEGUI" desde las directivas de includes en la cabecera del Tutorial Básico 7.

Los directorios include del proyecto


Añade las siguientes dos líneas a tu lista de directorios include en los proyectos.
CEGUI_HOME/include
CEGUI_HOME/include/CEGUI
Directorios de Librerías del proyecto
CEGUI_HOME/lib

Librerías de dependencias adicionales del proyecto

Windows

Debug
CEGUIBase_d.lib
CEGUIOgreRenderer_d.lib
Release
CEGUIBase.lib
CEGUIOgreRenderer.lib

Mueve DLLs


En Windows, necesitas copiar los siguientes DLLs al directorio de trabajo del binario:
CEGUIBase.dll
CEGUIFalagardWRBase.dll
CEGUIOgreRenderer.dll
CEGUIExpatParser.dll
El último DLL asume que estas usando el comprobador por defecto Expat XML con CEGUI.

Compila el Código


Asegúrate de que puedes compilar y ejecutar este código antes de continuar.
La aplicación no debería hacer otra cosa que presentarse con una pantalla en blanco (presiona Escape para salir).
Si al ejecutar tienes problemas en el compilador o en el enlazador, comprueba tus ajustes.

Un corta introducción a CEGUI


CEGUI es una librería GUI con muchas posibilidades que puede ser embebida en aplicaciones 3D como Ogre (también soporta OpenGL, DirectX, y Irrlicht). Como Ogre es sólo una librería gráfica (no hace otras cosas como sonido, física, etc), CEGUI es sólo una librería gráfica, lo que significa que no hace sus propios renderizados se acopla a los eventos de ratón y teclado. De hecho, para que CEGUI renderice todo, tienes que proporcionar un renderizador (renderer) (que es la librería CEGUIOgreRenderer que viene con CEGUI), y para que incluso comprenda los eventos de ratón y teclado tienes que inyectarlos manualmente en el sistema. Esto se ve incómodo al principio, pero en realidad es muy poco código. También te permite tener control completo sobre el renderizado y la entrada.

Hay muchos aspectos de CEGUI y muchos temas que no te serán familiares (incluso si has usado otros sistemas GUI antes). Intentaré introducirte lentamente en ellos sobre la marcha.

Integrando con Ogre

Definiendo grupos de recursos CEGUI


CEGUI como Ogre tiene varios tipos de recursos que necesita para funcionar. Tiene varios manejadores de recursos (como Ogre) que necesita para encontrar sus localizaciones de recursos respectivas. Además, necesitas definir los grupos de recursos necesarios y sus localizaciones sin resources.cfg.
La distribución de CEGUI instala sus recursos en diferentes localizaciones dependiendo de la plataforma.
Para una instalación Linux usual se instalan dentro de /usr/local/share/CEGUI o
/usr/share/CEGUI.

Añade el siguiente resources.cfg - reemplaza "path_to_cegui" con la ruta a los archivos de datos de CEGUI.
[Imagesets]
FileSystem=path_to_cegui/imagesets
[Fonts]
FileSystem=path_to_cegui/fonts
[Schemes]
FileSystem=path_to_cegui/schemes
[LookNFeel]
FileSystem=path_to_cegui/looknfeel
[Layouts]
FileSystem=path_to_cegui/layouts

Inicializando CEGUI


Busca la función createScene y añade el siguiente código:
mRenderer = &CEGUI::OgreRenderer::bootstrapSystem();
Ahora que CEGUI ha sido inicializado, necesitamos establecer los grupos de recursos por defecto para cada manejadores de recursos CEGUI.
Añade lo siguiente:
CEGUI::Imageset::setDefaultResourceGroup("Imagesets");
CEGUI::Font::setDefaultResourceGroup("Fonts");
CEGUI::Scheme::setDefaultResourceGroup("Schemes");
CEGUI::WidgetLookManager::setDefaultResourceGroup("LookNFeel");
CEGUI::WindowManager::setDefaultResourceGroup("Layouts");
Como has visto, usamos estos grupos de recursos que hemos definido sin resources.cfg. CEGUI es muy personalizable, y te permite definir el look and feel de tu aplicación cambiando su piel (scheme(esquema), en términos de CEGUI).No cubriremos como poner piel a la librería en el tutorial, asi que si deseas saber más, consulta el sitio web de CEGUI.
La siguiente línea de código selecciona la piel:
CEGUI::SchemeManager::getSingleton().create("TaharezLook.scheme");
La siguiente cosa que tenemos que hacer es establecer el cursor por defecto del ratón:
CEGUI::System::getSingleton().setDefaultMouseCursor("TaharezLook", "MouseArrow");
El primer parámetro especifica el Imageset y el segundo específica el nombre de la imagen a usar desde ese Imageset.

A través de esta serie de tutoriales usaremos CEGUI para msotrar el cursor del ratón. Es posible usar otra librería GUI para renderizar el ratón, o simplemente crear tu propio cursor de ratón usando Ogre directamente. Si estas usando CEGUI sólo para el cursor del ratón y te preocupa la cantidad de uso de memoria y espacio en disco que coge tu juego, puedes mirar una de estas otras opcioes para reemplazar a CEGUI.

Nota que en el último snippet de código hemos establecido el cursor del ratón por defecto, pero no establecimos el cursor del ratón directamente usando la función MouseCursor::setImage como se verá en los últimos tutoriales. esto es porque en este tutorial estaremos sobre alguna clase de ventana CEGUI (piensa que debe ser invisible), así establece el cursor por defecto, en efecto, ahora la el cursor de ratón será la imagen que hemos seleccionado. Si hemos establecido el cursor del ratón directamente y no lo establecimos por defecto, el cursor de ratón debería estar invisible cada vez que pases por encima de una ventana CEGUI (que, en este tutorial, será todo el tiempo). Por otra parte, estableciendo la imagen por defecto del ratón no hará nada si ninguna ventana de CEGUI se muestra, que será el caso de los últimos tutoriales. En esta situación, llamando a MouseCursor::setImage se mostrará el cursor para la aplicación. Ejemplo:
CEGUI::MouseCursor::getSingleton().setImage( CEGUI::System::getSingleton().getDefaultMouseCursor());

Eliminando SDKTrays


Antes de ir más allá, necesitamos eliminar los SDKTrays de OgreBites de nuestra aplicación.
Haremos esto sobreescribiendo dos funciones createFrameListener y frameRenderingQueued

createFrameListener


Copia los contenidos de la funcion BaseApplication::createFrameListener a BasicTutorial7::createFrameListener y elimina el bit donde SDKTrays esta creado y el debug superpuesto instalado.
Se deberia parecer a esto:
void BasicTutorial7::createFrameListener(void)
{
 Ogre::LogManager::getSingletonPtr()->logMessage("* Initializing OIS *");
 OIS::ParamList pl;
 size_t windowHnd = 0;
 std::ostringstream windowHndStr;
 
 mWindow->getCustomAttribute("WINDOW", &windowHnd);
 windowHndStr << windowHnd;
 pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
 
 mInputManager = OIS::InputManager::createInputSystem( pl );
 
 mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, true ));
 mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject( OIS::OISMouse, true ));
 
 mMouse->setEventCallback(this);
 mKeyboard->setEventCallback(this);
 
 // Establece el tamanyo inicial del recorte de raton
 windowResized(mWindow);
 
 // Registralo como un Window listener
 Ogre::WindowEventUtilities::addWindowEventListener(mWindow, this);
 
 mRoot->addFrameListener(this);
}

frameRenderingQueued


Tambien necesitamos sobreescribir BaseApplication::frameRenderingQueued.
Haz que parezca como esto:
bool BasicTutorial7::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
 if(mWindow->isClosed())
 return false;
 
 if(mShutDown)
 return false;
 
 // Necesitas capturar/actualizar cada dispositivo
 mKeyboard->capture();
 mMouse->capture();
 
 return true;
}
Solo eliminamos mTrayMgr y las partes de mDetailsPanel.

Inyectando Eventos de Tecla


CEGUI no maneja la entrada de ninguna forma. No lee movimientos del ratón o entrada desde teclado. En vez de esto permite que el usuario inyecte los eventos de tecla y ratón dentro del sistema. La siguiente cosa que necesitamos hacer es manejar los eventos de tecla. Si estas trabajando con CEGUI, necesitarás tener el ratón y el teclado en modo búfer para que puedas recibir los eventos directamente e inyectarlos tal y como ocurran.
Busca la función keyPressed y añade el siguiente código:
CEGUI::System &sys = CEGUI::System::getSingleton();
sys.injectKeyDown(arg.key);
sys.injectChar(arg.text);
return true;
Después de conseguir el sistema objeto, necesitamos hacer dos cosas:
La primera es inyectar el evento key down dentro de CEGUI.
El segundo es inyectar el carácter actual que fue presionado.
Es muy importante inyectar el carácter apropiadamente ya que inyectando el key down no siempre hará que se produzcan los resultados apropiados usando un teclado no ingles. El injectChar fue diseñado con el soporte Unicode en mente.
Ahora necesitamos inyectar el evento key up dentro del sistema.
Busca la función keyReleased y añade el siguiente código:
CEGUI::System::getSingleton().injectKeyUp(arg.key);
return true;
Nota que no necesitamos inyectar un carácter de evento up, sólo el evento tecla up se necesita.

Convirtiendo e Inyectando Eventos de Ratón


Ahora que hemos terminado de tratar con la entrada de teclado, necesitamos ocuparnos de la ratón.
Tenemos un pequeño problema que necesitaremos direccionar.
Cuando inyectamos los eventos key up y key down dentro de CEGUI nunca tuvimos que convertir la tecla. Ambos OIS y CEGUI usan los mismos códigos de tecla para la entrada de teclado. Lo mismo no es cierto para los botones del ratón.
Antes de que podamos inyectar los botones de ratón presionados en CEGUI, necesitaremos escribir una función que convierta las referencias de botón OIS en las CEGUI.
Añade el siguiente código a BasicTutorial7.cpp:
CEGUI::MouseButton convertButton(OIS::MouseButtonID buttonID)
{
 switch (buttonID)
 {
 case OIS::MB_Left:
 return CEGUI::LeftButton;
 
 case OIS::MB_Right:
 return CEGUI::RightButton;
 
 case OIS::MB_Middle:
 return CEGUI::MiddleButton;
 
 default:
 return CEGUI::LeftButton;
 }
}
Puede estar como función estática, así que no necesitas declararlo en la cabecera.

Ahora estamos listos para inyectar los eventos de ratón.
Busca la función mousePressed y añade el siguiente código:
CEGUI::System::getSingleton().injectMouseButtonDown(convertButton(id));
return true;
Debería ser autoexplicativo.
Convertimos la id del botón que fue pasado, y se envia el resultado a CEGUI.

Busca la función mouseReleased y añade esta línea de código:
CEGUI::System::getSingleton().injectMouseButtonUp(convertButton(id));
return true;
Finalmente, necesitamos inyectar el movimiento de ratón dentro de CEGUI
El objeto CEGUI::System tiene una función injectMouseMove que espera movimientos relativos del ratón.
El manejador OIS::mouseMoved nos da estos movimientos relativos en las variables state.X.rel variable y state.Y.rel.
Busca la función mouseMoved y añade el siguiente código:
CEGUI::System &sys = CEGUI::System::getSingleton();
sys.injectMouseMove(arg.state.X.rel, arg.state.Y.rel);
// Rueda de scroll
if (arg.state.Z.rel)
 sys.injectMouseWheelChange(arg.state.Z.rel / 120.0f);
return true;
120 es un "número mágico" usado por Microsoft desde siempre. OIS usa el mismo número mágico. GLUT, por ejemplo, no lo usa. Google si quieres encontrar más información.

Esto es todo. Ahora CEGUI esta completamente ajustado y recibe eventos de ratón y de teclado.

Ventanas, Hojas, y Widgets

Introducción


CEGUI es muy diferente de la mayoría de sistemas GUI.
En CEGUI, todo lo que es mostrado es una subclase de la clase CEGUI::Window, y una ventana puede tener cualquier número de ventanas hijas.
Esto signica que cuando creas un frame para contener múltiples botones, esto nunca ocurrirá en la práctica.
La razón de esto, mencione que todo esto es cuando estas mirando a un widget en particular que has colocado en la aplicación, todos son llamados por Windows, y son accedidos por funciones que los llaman.
En la mayoría de usos prácticos de CEGUI, no crearás cada objeto individual a través de código.
En vez de esto crearás un fondo GUI para tu aplicación en un editor como CEGUI Layout Editor.
Después colocarás todas las ventanas, botones, y otros widgets en la pantalla como quieras, el editor salva el fondo dentro de un archivo de texto.
Debes cargar este fondo más tarde dentro ya que CEGUI llama a una hoja GUI (lo cual también es una subclase de CEGUI::Window).

Finalmente, sabemos que CEGUI contiene un buen número de widgets que puedes usar en tu aplicación.
No los trateremos en este tutorial, así que si decides usar CEGUI, mira su sitio web para más información.

Cargando una Hoja


En CEGUI cargar una hoja es muy fácil de hacer. La clase WindowManager proporciona una función "loadWindowLayout" que carga la hoja y la pone en un objeto CEGUI::Window.
Entonces llama a CEGUI::System::setGUISheet para mostrarlo.
No usaremos esto en este tutorial. Ejemplo de uso.

No añadir esto al tutorial:
// No anyadir esto al programa
CEGUI::Window *guiRoot = CEGUI::WindowManager::getSingleton().loadWindowLayout("TextDemo.layout");
CEGUI::System::getSingleton().setGUISheet(guiRoot);
Esto establece la hoja que se muestra actualmente.
Puedes conseguir esta hoja llamando a System::getGUISheet.
Puedes también cambiar la hoja GUI llamando a setGUISheet con la hoja que quieras poner.

Creación manual de un Objeto


Como dije antes, la mayoría del tiempo usas CEGUI, las hojas de GUI las crearás usando un editor.
Ocasionalmente, sin embargo, necesitarás crear manualmente un widget que poner en la pantalla.
En este ejemplo, añadiremos un botón Quit de salida al que luego añadiremos la funcionalidad.
Ya que queremos añadir más de un botón Quit a la pantalla durante el tiempo de este tutorial, necesitamos crear primeramente una CEGUI::Window por defecto que contenga todos los widgets que se crearán.

Añade esto al final de la función createScene:
CEGUI::WindowManager &wmgr = CEGUI::WindowManager::getSingleton();
CEGUI::Window *sheet = wmgr.createWindow("DefaultWindow", "CEGUIDemo/Sheet");
Esto usa el WindowManager para crear una "DefaultWindow" (ventana por defecto) llamada "CEGUIDemo/Sheet".
Mientras, podríamos nombrar la ventana como quisieramos, es muy común (y aconsejable) que el nombre del widget este de forma jerárquica "SomeApp/MainMenu/Submenu3/CancelButton".

La siguiente cosa que necesitamos hacer es crear el botón de Quit y establecer su tamaño:
CEGUI::Window *quit = wmgr.createWindow("TaharezLook/Button", "CEGUIDemo/QuitButton");
quit->setText("Quit");
quit->setSize(CEGUI::UVector2(CEGUI::UDim(0.15, 0), CEGUI::UDim(0.05, 0)));
CEGUI usa un sistema "de dimension unificada" para sus tamanyos y posiciones.
Cuando estableces el tamaño debes crear un objeto UDim para decirle que tamaño debería tener.
El primer parametro es el tamaño relativo del objeto en relación a su padre.
El segundo parámetro es el tamaño absoluto del objeto en píxeles.
Lo importante es que sólo tienes que establecer uno de los dos parámetros de UDim.
El otro parámetro debe ser O.
Así que en este caso tenemos que hacer un botón con el 15% de su padre y un 5% de alto.
Si queremos especificar que debería ser de 20x5 píxeles, deberíamos establecer el segundo parámetro en ambas llamadas a UDim para que sean 20 y 5.

La última cosa que tenemos que hacer es acoplar el botón Quit a la hoja que hemos creado, y entonces establecer la hoja GUI actual para que el sistema use esta hoja:
sheet->addChildWindow(quit);
CEGUI::System::getSingleton().setGUISheet(sheet);
Ahora si compilas y ejecutas tu aplicación veras un botón Quit en la esquina superior izquierda de la pantalla, pero no hace nada todavía si pulsas sobre él.

Eventos


Los eventos en CEGUI son muy flexibles.
En vez de usar una interfaz que implementes para recibir eventos, usa un mecanismo de devolución de llamada que enlaza con cualquier función pública (con la firma de método apropiada claro) que es el manejador de evento.
Desafortudamente esto también significa que el registro de eventos es un poco más complicado.
Ahora registraremos el manejador para el evento click del botón Quit para salir del programa cuando se presione.
Para hacer esto, primero necesitamos un puntero al botón Quit que hemos creado en la sección anterior.

Añade el siguiente código a BasicTutorial7::createScene después de he hayas creado la ventana del botón quit:
quit->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&BasicTutorial7::quit, this));
Esto subscribirá el evento pulsado.
Cada widget en CEGUI tiene un conjunto de eventos que soporta, y todos empiezan con "Event".
El primer parámetro a subscribeEvent es el evento en si mismo.
El segundo parámetro es un objeto Event::Subscriber.
Cuando estamos creando un objeto Subcriber, la primera cosa que tenemos que pasarle es un puntero a la función que manejará el evento (nota que el símbolo & nos da el puntero a la función).
La segunda cosa que tenemos que pasar al subscriber es el objeto BasicTutorial7 que maneja el evento.
Eso es todo!
Nuestra función BasicTutorial7::quit (que ya hemos definido) manejará el click del ratón y terminará el programa.

Añade el siguiente código a BasicTutorial7::quit (reemplazando los contenidos):
mShutDown = true;
return true;
Compila y ejecuta tu aplicación para comprobarla.

Una cosa que te tienes que dar cuenta es que creamos cualquier número de funciones para manejar los eventos CEGUI.
La única restricción es que deben devolver un bool y que tienen que tener un único parámetro de tipo "const CEGUI::EventArgs &".
Para más información sobre eventos (y subscribirse a ellos), asegúrate de mirar el sitio web de CEGUI.

Renderizar a Textura


Una de las cosas más interesantes que podemos hacer con CEGUI es crear una ventana renderizada de textura.
Esto nos permitirá crear un segundo Viewport en el cual podemos renderizar directamente un widget CEGUI.
Para hacer esto, primero necesitamos establecer una escena .

Añade el siguiente código al final de la función createScene:
mSceneMgr->setAmbientLight(Ogre::ColourValue(1, 1, 1));
mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8);
Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");
Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Ogre::Vector3(0, 0, -300));
headNode->attachObject(ogreHead);
Ahora debemos crear la RenderTexture.
El objeto RenderSystem proporciona la funcionalidad de renderizar a textura. Para hacer esto creamos una textura con la función TextureManager::createManual.

Para este programa crearemos una textura de 512 x 512:
Ogre::TexturePtr tex = mRoot->getTextureManager()->createManual(
 "RTT",
 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
 Ogre::TEX_TYPE_2D,
 512,
 512,
 0,
 Ogre::PF_R8G8B8,
 Ogre::TU_RENDERTARGET);
Ogre::RenderTexture *rtex = tex->getBuffer()->getRenderTarget();
Mirar la referencia API para más información sobre esta función.

Lo siguiente que necesitamos crear es una Cámara y un Viewport para mirar a la escena que hemos creado.
Nota que hemos cambiado un par de opciones del Viewport, incluyendo el apagado de Superposiciones... lo que es muy importante o conseguirás CEGUI y superposiciones de Ogre dentro de nuestra miniventana.
Ogre::Camera *cam = mSceneMgr->createCamera("RTTCam");
cam->setPosition(100, -100, -400);
cam->lookAt(0, 0, -300);
Ogre::Viewport *v = rtex->addViewport(cam);
v->setOverlaysEnabled(false);
v->setClearEveryFrame(true);
v->setBackgroundColour(Ogre::ColourValue::Black);
Nota que hemos añadido el Viewport a la textura en si misma (como oposición a la RenderWindow, lo que es donde normalmente añadimos los Viewports).

Ahora que hemos creado nuestra escena y nuestra textura, necesitamos empotrarla dentro de CEGUI.
Puedes crear una CEGUI::Texture desde cualquier textura de Ogre llamando a la función CEGUI::OgreRenderer::createTexture:
CEGUI::Texture &guiTex = mRenderer->createTexture(tex);
Desafortudamente, aquí es donde las cosas se complican.
En CEGUI nunca puedes tratar con una única textura o una única imagen.
CEGUI funciona con conjuntos de imágenes en vez de con imágenes individuales.
Es muy útil trabajar con rejilas enteras de imágenes cuando estas intentando definir el look and feel de una piel que has creado ( por ejemplo, mira en TaharezLook.tga en la carpeta datafiles/imagesets del CEGUI SDK para ver como se ve un conjunto de imágenes).
Sin embargo, incluso cuando estas definiendo una única imagen, debes crear un conjunto entero de imagen.

Esto se hace así:
CEGUI::Imageset &imageSet =
CEGUI::ImagesetManager::getSingleton().create("RTTImageset", guiTex);
imageSet.defineImage("RTTImage",
 CEGUI::Point(0.0f, 0.0f),
 CEGUI::Size(guiTex.getSize().d_width,
 guiTex.getSize().d_height),
 CEGUI::Point(0.0f, 0.0f));
La primera línea crea el conjunto de la imagen (llamado "RTTImageset" ) desde la textura que le hemos proporcionado.
La siguiente línea (que llama a defineImage), específica que la primera y única imagen se llama "RTTImage" y es tan grande como la textura guiTex entera que hemos proporcionado.
Finalmente necesitamos crear el widget StaticImage que guardará la textura renderizada.
La primera parte no tiene diferencias al crear cualquier otra ventana:
CEGUI::Window *si = CEGUI::WindowManager::getSingleton().createWindow("TaharezLook/StaticImage", "RTTWindow");
si->setSize(CEGUI::UVector2(CEGUI::UDim(0.5f, 0),
 CEGUI::UDim(0.4f, 0)));
si->setPosition(CEGUI::UVector2(CEGUI::UDim(0.5f, 0),
 CEGUI::UDim(0.0f, 0)));
Ahora necesitamos especificar que imagen esta mostrando el widget StaticImage.
Otra vez, ya que CEGUI siempre trata con conjuntos de imagen y no con imágenes individuales, debemos ahora capturar el nombre exacto de la imagen desde el conjunto image, y mostrarlo:
si->setProperty("Image", CEGUI::PropertyHelper::imageToString(&imageSet.getImage("RTTImage")));
Parece como si hubieramos empaquetado una textura dentro de un conjunto de imagen sólo para desempaquetarlo otra vez, eso es porque es lo que hemos hecho.
Manipular imágenes en CEGUI no es una de las cosas más fáciles de hacer en la librería.

La última cosa que necesitamos hacer es añadir el widget StaticImage a la hoja de GUI que creamos anteriormente:
sheet->addChildWindow(si);
Ahora que hemos terminado. Compila y ejecuta la aplicación. :-)

Conclusión


Alternativas


Aquí estan unas pocas alternativas a CEGUI:

  • QuickGUI
  • MyGUI

Más Información


Hay también varios lugares donde puedes conseguir información sobre CEGUI.

  • Aplicación Práctica - Algo con un poco más de enjundia - Un tutorial más en profundidad que este.



Siguiente, Tutorial Básico 8 usando Múltiples SceneManagers