viernes, 30 de abril de 2010

Personalizando nuestras aplicaciones 2ª (Botones, Labels ....)

En este tuturial aprenderemos a crear nuestro botones y labels, y demas utilidades que nos ofrece la GUI de Ogre.

En la clase SdkTraylistener, explicada un poco por encima en el tutoriales anteriores, esta clase ademas de crear botones, labels... un largo etc, es utilizada tambien para recojer sus estados. Vamos a intentar explicar una parte del codigo que se dedica a registrar los eventos de la ventana a la libreria de Ogre.

En el metodo BaseApplication::createFrameListener() esta el siguiente codigo:

//Este codigo es para meter registros de log en el fichero Ogre.log, de la capeta bin\debug o release
Ogre::LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
//Creamos una lista de parametros del OIS
OIS::ParamList pl;

Inicializamos un mejador de ventanas, tambien llamado en la API WIN32: HWND, digamos que es un identificador de la ventana, cada ventana de window que abres en tu S.O. necesita un identificador, pues estamos registrando el que nos a dado WindowsXP.

size_t windowHnd = 0;


//Creamos un flujo de entrada para crear valores String
std::ostringstream windowHndStr;


//El objeto mWindow es la venta fisica que acaba de crear nuestro programa en el S.O. le pasamos el windowHnd para que nos devuelva el identificador de ventna creado.
Se lo damos al flujo de entrada y se crea un String con un numero que se lo introducimos al ParamList
mWindow->getCustomAttribute("WINDOW", &windowHnd);
windowHndStr << windowHnd; pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); //Aqui creamos el InputManager con este PAramList creado anteriormente, que es el objeto padre que recojera cualquier evento producido en la ventana, raton, teclado, minimizar, maximizar.... mInputManager = OIS::InputManager::createInputSystem( pl ); //Creamos los objetos mKeyBoard y mMouse con ese InputManager y al ser el BaseApplication una clase derivada de KeyListener y MouseListener, les añadimos mKeyBoard y mMouse esta clase para recojer sus eventos. mKeyboard = static_cast(mInputManager->createInputObject( OIS::OISKeyboard, true ));
mMouse = static_cast(mInputManager->createInputObject( OIS::OISMouse, true ));


mMouse->setEventCallback(this);
mKeyboard->setEventCallback(this);


//Aqui establecemos el tamaño de ventan para darle un ancho y alto al nuestro raton
windowResized(mWindow);


//Registramos en Ogre la ventana y el BAseApplication que deriva de WIndowEventListener
Ogre::WindowEventUtilities::addWindowEventListener(mWindow, this);


//Aqui inicializamos en objeto SdkTrayListener con la ventana, el raton y el BaseApplication
mTrayMgr = new OgreBites::SdkTrayManager("InterfaceName", mWindow, mMouse, this);
//Aqui muestra el panel de FPS
mTrayMgr->showFrameStats(OgreBites::TL_BOTTOMLEFT);
//Inicializa nuestro Logo, ya modificado en el tutorial anterior
mTrayMgr->showLogo(OgreBites::TL_BOTTOMRIGHT);


//Una vez explicado esto ya entendemos como se enlaza la ventana con la librearia Ogre y OIS, para recojer los eventos del MouseListener y KeyListener y sus metodos:


virtual bool keyPressed( const OIS::KeyEvent &arg );
virtual bool keyReleased( const OIS::KeyEvent &arg );
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 );

Una vez echo esto en el metodo createFrameListener() al final vamos a crear un boton y un label :

mTrayMgr->createButton(OgreBites::TL_BOTTOM, "Boton","Esto es un boton",200);
mTrayMgr->createLabel(OgreBites::TL_TOP,"Label","FrakTeam Logo",400);

Con estos metodos creamos dos Widgets dentro de la clase mTrayMgr, los Widgets con la clase Padre de todos los elementos creado de SdkTray. Utilizamos el metodo mousePressed, para saber que ha pulsado:

bool personalizando2::mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id){
if(mTrayMgr->injectMouseDown(evt,id)){
OgreBites::Label *label = static_cast(mTrayMgr->getWidget("Label"));
OgreBites::Button *boton = static_cast(mTrayMgr->getWidget("Boton"));
if(boton->getState() == OgreBites::BS_DOWN){
label->setCaption("Has pulsado el boton");
} else {


label->setCaption("No es el boton");
}
return true;
} else {
static_cast(mTrayMgr->getWidget("Label"))->setCaption("Has pulsado en vacio");
}
mCameraMan->injectMouseDown(evt,id);
return true;


}

Compilamos y veremos algo así:


Como vemos en este codigo cojemos el evento MouseEvent y el boton pulsado del raton MouseButtonID, y se los pasamos a mTrayMgr->injectMouseDown(), este metodo busca todos sus Widgets, creado por la posición y cambia el estado del pulsado por el cursor, dependiendo la posición del mismo.

Un vez pasado el metodo injectMouseDown, si hemos pulsado el boton habrá cambiado su estado, utilizamos el metodo getWidget(Nombre), y le realizamos un static_cast a OgreBites::Button, hacemos la conversión de Widgets a Button, preguntamos por su estado y vemos que es OgreBitess::BS_DOWN, y cambiamos el valor del caption del Label, realizando la misma operación de sttatic_cast.

Esto es un ejemplo, pero lo suyo es tener objetos Button y Label como privados, para no tener que realizar un static_cast cada vez que pulsemos un boton en nuestra aplicación, de todas formas solo es un ejemplo.

El metodo de mCameraMan->injectMouseDown(), como expliqué en tutoriales anteriores, este objeto es para utilizar los eventos de la camara, si no hemos pulsado ningun Widgets, entoces le pasa el valor del raton a la camara.

Aqui os paso el Codigo de ejemplo por si lo quereis ver y realizar Debug. SRC Ejemplo

Aqui os paso los binarios del programa solo para Windows. Se ejecutará en modod OpenGL, si quieres ejecutarlo en modo DirectX, necesitas terner instalado los Directx en tu equipo y descomentar el fichero plugins.cfg, la linea:

Plugin=RenderSystem_Direct3D9
# Plugin=RenderSystem_Direct3D10
# Plugin=RenderSystem_Direct3D11

Descomenta dependiendo la que tengas.

Binarios Ejemplo

jueves, 29 de abril de 2010

Personalizando nuestras aplicaciones (Cambio del logo y cursor)

Para darle un toque personalizado a nuesttra apliaciónes en ogre deberiamos cambiar un poco la estetica, de los mimos, para ellos deberemos ver el resoirces.cfg:

# Resources required by the sample browser and most samples.
[Essential]
Zip=../../media/packs/SdkTrays.zip
FileSystem=../../media/thumbnails


# Common sample resources needed by many of the samples.
# Rarely used resources should be separately loaded by the
# samples which require them.
[Popular]
FileSystem=../../media/fonts
FileSystem=../../media/materials/programs
FileSystem=../../media/materials/scripts
FileSystem=../../media/materials/textures
FileSystem=../../media/materials/textures/nvidia
FileSystem=../../media/models
FileSystem=../../media/particle
FileSystem=../../media/DeferredShadingMedia
FileSystem=../../media/PCZAppMedia
FileSystem=../../media/RTShaderLib
FileSystem=../../media/RTShaderLib/materials
Zip=../../media/packs/cubemap.zip
Zip=../../media/packs/cubemapsJS.zip
Zip=../../media/packs/dragon.zip
Zip=../../media/packs/fresneldemo.zip
Zip=../../media/packs/ogretestmap.zip
Zip=../../media/packs/ogredance.zip
Zip=../../media/packs/Sinbad.zip
Zip=../../media/packs/skybox.zip


[General]
FileSystem=../../media

Todas las apliaciones que usan el la libreria SdKTray.h, utiliza el archivo comprimido SdkTray.zip que contiene imagenes del logo, cursor, botones, labels.... y tambien hay otros ficheros tiene un codigo para la lectura de los mismos, lo llamo templates. Abrimos el zip SdkTray.zip y veremos muchas imagenes formato


Todos los png son las imagenes para usar como botones y textura de imagenes, archivos .overlay, material, fontdef, y dos ficheros ttf que son para el formato de fechas. Abrimos el fichero sdktrays.material y nos fijamos en el siguiente codigo:

material SdkTrays/Logo : SdkTrays/Base
{
technique
{
pass
{
texture_unit
{
texture sdk_logo.png
}
}
}
}

Con este codigo Ogre le pone un nombre para identificar el material, que en este caso será el logo, que irá introducido como dentro de un Panel, aqui identficaremos los materiales de nuestros objetos. Bueno ahora solo tenemos que meter nuestro logo dentro del zip y idicarle en el sdktrays.material, el nombre del fichero. Con el cursor realizamos la misma operación, idientificamos dentro de sdktrays.material, el cursor y cambiamos el nombre uevo cursor.

Ahora si queremos personalizar el panel que contiene nuestro logo abrimos el fichero sdktrays.overlay, y vemos el siguiente codigo:

template container Panel(SdkTrays/Logo)
{
metrics_mode pixels
material SdkTrays/Logo
horz_align center
width 128
height 53
}

Aumentamos el valor de width a 256 y height a 63, para darle el tamaño adecuado, para el nuestro logo de freakteam. Si qusieramos cambiar el temaño del cursor haríamos la misma operación. Una vez echo esto tendriamos nuestro SdkTray.zip, un poco mas personalizado, solo falta cambiar los botones y labels, para darle un mejor aspecto, que ya veremos en los proximos capitulos.

Ahora solo nos queda cambiar el icono de la Ventana de arriba a la izquierda y el icono del ejecutable, ese icono se encuentra en nuestro proyecto en Resources File, podriamos nuestro logo, para hacer la transformación de PNG a ICO, podriamos utilizar este enlace, una vez creado modificamos el nombre y le ponemos el mismo que tiene nuestro proyecto en VS2008.

Convertir PNG a ICO

Tendriamos nuestro logo en ICO:


Voy dejar los enlaces del SdkTRay.zip modificado y el ICO, para descargar y realizar pruebas: SourceForge FreakTeam Files

miércoles, 28 de abril de 2010

BaseApplication.h y cpp

En este tutorial vamos a explicar la Clase BaseApplication, que se encuentra su declaracion de clase en BaseApplication.h ( abreviaré con H), y el desarrollo de la misma en BaseApplication.cpp ( abreviaré con CPP ). Esta clase se genera una vez creado el proyecto con el AppWizard del VS2008, por lo que podemos modificarla y crear la nuestra propia, pero esta clase es la que contiene basicamente casi todas la funcionalidades, para el nivel de los tutoriales mas basicos.

El codigo:

class BaseApplication : public Ogre::FrameListener, public Ogre::WindowEventListener, public OIS::KeyListener, public OIS::MouseListener, OgreBites::SdkTrayListener
{
public:
BaseApplication(void);
virtual ~BaseApplication(void);


virtual void go(void);


protected:
virtual bool setup();
virtual bool configure(void);
virtual void chooseSceneManager(void);
virtual void createCamera(void);
virtual void createFrameListener(void);
virtual void createScene(void) = 0; // Override me!
virtual void destroyScene(void);
virtual void createViewports(void);
virtual void setupResources(void);
virtual void createResourceListener(void);
virtual void loadResources(void);
virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt);


virtual bool keyPressed( const OIS::KeyEvent &arg );
virtual bool keyReleased( const OIS::KeyEvent &arg );
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 );


//Adjust mouse clipping area
virtual void windowResized(Ogre::RenderWindow* rw);
//Unattach OIS before window shutdown (very important under Linux)
virtual void windowClosed(Ogre::RenderWindow* rw);

En la primera linea vemos como se declara la clase y empieza a heredar de otras, de la librearia de Ogre, las que vamos a detallar a continuación:

  • FrameListener : Esta clase, para para escojer eventos entre Frames, realizando busqueda por internet cito lo siguiente. Un “listener” (oyente) es una interfaz diseñada para ser llamada cuando ocurren ciertos eventos. Esta clase (FrameListener) define la interfaz que se relaciona a eventos de cuadros (frame). Lo anterior significa que si yo defino un FrameListener, mi aplicación sería capaz de realizar acciones entre cuadro y cuadro. Lo más común es utilizarlo para la captura de eventos de teclado y ratón, o para actualizar el movimiento y la posición de los diferentes objetos ya sea manualmente, o también por medio de alguna biblioteca de simulación de físicas, aunque no está limitado a esas tareas. Siempre que tengamos alguna acción que queramos realizar en cada cuadro, entonces debemos utilizar un FrameListener. La clase FrameListener contiene 2 métodos virtuales, frameStarted() y frameEnded(). El método frameStarted() es llamado al inicio del cuadro, antes de hacer la actualización de la escena, y el método frameEnded() es llamado después de haber hecho la actualización de la escena y antes de actualizar el siguiente cuadro. Ambos métodos regresan un valor boolean, que le indica al motor gráfico si debe seguir actualizando, o salir del ciclo de actualización (render). Si no re-definimos estos métodos, el valor por defecto es true, o sea, seguir actualizando.
  • Los métodos frameStarted() y frameListener() tienen además un parámetro de tipo FrameEvent. Este FrameEvent no es mas que una estructura que contiene información acerca del evento, básicamente el tiempo transcurrido (en segundos) desde el último evento (timeSinceLastEvent) y el tiempo transcurrido desde el último cuadro (timeSinceLastFrame). La diferencia entre uno y otro valor es que el primero nos cuenta el tiempo que ha pasado de frameStarted() a framEnded() y viceversa, y el otro el tiempo de frame a frame, o sea de frameStarted() a frameStarted() y de frameEnded() a frameEnded(). De la web: Diario de un programador
  • WindowEventListener: Es para recojer eventos de ventana, en el H y CPP, se implementas los metodos windowClosed y windowResize, que explicaremos mas a delante.
  • MouseListener y KeyListener: Pues como su nombre indica, para recojer eventos de teclado y raton, por ejemplo el keyPressed, para recojer las teclas pulsadas, todos estos metodos por parametro se le pasa un KeyEvent o MouseEvent, que son los que llevan la información del evento.
  • OgreBites::SdkTrayListener: Es el oyente de eventos de Botones, Labels, es una utilidad que carga y crea todo tipo de utulidades basicas, como por ejemplo el ProgressBar.

Estos son alguno de los objetos mas relevantes que detallaremos a continuación:

  • Ogre::Root *mRoot; Es el objeto raiz, donde se crea la ScenaManager y se instala puglins, muchas mas opciones uqe veremos mas adelante, si hacemos un simil con la pintura el mRoot sería el pintor.
  • Ogre:: Camera *Camera; Es la camara, el objeto que se configurá con su ViewPort, para su uso.
  • gre::SceneManager* mSceneMgr; Es la escena de todo tu aplicación, la que de ella cuelga todos los SceneNodes, y demas objetos, si seguimos con el simil de pintura, el SceneNode es el pinzel, la SceneManager es el lienzo.
  • Ogre::RenderWindow* mWindow; Es la ventana fisica del S.O., la que tenemos que pasarle los yentes de teclado y raton. Con ella se pude sacar información del usuario, por ejemplo el tamaño de ventana, para configurar el ViewPort de la camara.
  • Ogre::String mResourcesCfg, Ogre::String mPluginsCfg; Sion las rutas de los ficheros resources.cfg y puglins.cfg
  • OgreBites::SdkTrayManager* mTrayMgr; Es el objeto que cargará los modelos de Utilidades de Botones, progressBar, Logo, hará de yente de los mismos para su uso. Tiene mas utilidades que veremos poco a poco.
  • OgreBites::SdkCameraMan* mCameraMan; Es el controlador basico de la camra, con ella se le pueden pasar los eventos del raton, para poder moverla con libertad
  • OgreBites::ParamsPanel* mDetailsPanel; Es un panel grafico para representar datos, que se crea y configura con el SdkTrayListener

En los siguientes tutoriales, seguiremos explicando un poco el funcionamiento de Ogre.

martes, 27 de abril de 2010

Proximos tutoriales

En los siguientes tutoriales, explicaré el codigo de BaseApplication.h y cpp, cambiaremos el Logo y el cursor del raton, por el nuestro de FKT, explicarè como funcionan los templates y donde se ubican para poder modificar atributos, Colocaremos botones y labels y los modificaremos y por ultimo veremos ejemplos de rotaciones, posiciones y escala.

Un adelanto:

lunes, 26 de abril de 2010

Convertir Archivos 3ds a Mesh

Esta funcionalidad, nos será muy util, paa convertir ejemplos ya creado que hay en la red, y usarlos en nuestros ejemplos. Al haber gran cantidad de ejemplos de modelos 3d creados en 3d studio, y exportados con el formato 3ds, vamos a proceder explicar este tipo de conversión. Para los demas formatos: http://www.ogre3d.org/wiki/index.php/OGRE_Exporters

Requisitos:
Debemos tener instalado el OgreSDK con su variable de entorno OGRE_HOME y el Path con OGRE_HOME\bin\debug y OGRE_HOME\bin\release.


  1. Descargamos la aplicacion de MSDOS 3DS2MESH, de esta dirección http://r2d3.geldreich.net/downloads/3ds2mesh122.zip
  2. Una vez descargado y descomprimido, ya podemos empezar a utilizarlo, para ello nos tendremos que descargar un modelo 3d de ejemplo, hay muchos libres en internet, facilitaré uno: www.the3dstudio.com/ Nos descargamos uno en formato 3ds.
  3. Una vez lo tengamos descargado y descomprimido, nos vamos a msdos y usamos la siguiente comando. 3ds2mesh.exe -s -f miFile.3ds myNuevoMesh

Esto generará dos ficheros unos myNuevoMesh.material.mesh y myNuevoMesh.mesh

Ya tenemos creado nuestro .Mesh para renderizarlos con Ogre.

viernes, 16 de abril de 2010

Instalacion y introduccion de Ogre3D

Esta instalación se va a basar en Windows, en el futuro la intención es desarrollar para mac y linux, pero mientras estemos aprendiendo la lib de Ogre, lo haremos en windows por la facilidad de su IDE (Visual Studio 2008).

Un vez que tengamos instalado el IDE VS2008 Express, empezamos a descargar la SDK de DirectX, AlppWizad y la lib de Ogre hastala fecha de publicación de este tutorial es la Ogre SDK 1.7.

Esto son los enlaces:


Recuerda que nates de instalar el AppWizard debes de tener instalado el vs2008.

Una vez instalado la SDK de DirectX y el Appwizard, instala la SDK de Ogre, mas bien descomprime un ficheros en la misma ruta de descarga el ejecutable. Habra creado una carpeta con el nombre OgreSDK_vc9_v1-7-0, dicha carpeta la colocamos por ejemplo en la raiz de nuestro Disco duro.

c:\OgreSDK_vc9_v1-7-0.

Lo primero que debemos hacer es crear la variable de entorno de ogre (OGRE_HOME). Nos vamos a Propiedades MiPC > Opciones Avanzadas > Variables de Entorno y allí en variables del sistema creamos la nueva variables de entorno. OGRE_HOME con su valor c:\OgreSDK_vc9_v1-7-0

En la variable PATH, modificamos us valor, y al final añadimos ;%OGRE_HOME%/bin/release;%OGRE_HOME%/bin/debug.

Una vez creado, vamos a ver la estructura de carpetas instaladas:


  • OGRE_HOME\bin es la carpeta donde estaran ubicada los ejecutables de nuestros proyectos del modo Debug y Release de nuestras aplicaciones. 
  • boost_1_42 son .H y lib de utilidades de Ogre, ej: Clases Array, Exceptions...
  • include es la capeta donde se ubican todas las lib y .H del Core de Ogre, hay dos carpetas el Ogre y OIS, esta ultima son lib para el manejo de teclados , raton...
  • Lib ahí se encuentran las librearias de Ejecución de Ogre, en su modo Debug y Release.
  • media es donde se encuentran, los modelos de ejemplos y imagenes de los Samples, que utilizaremos tambien en nuestros tutoriales.
  • Samples son los ejemplos que viene con el SDK de Ogre, Efectos de Agua, Animación...Se ejecutan con el Projects/Browser.

Bueno una vez explicada la estructura de las carpetas mas importnates de Ogre procedemos a nuestro primer ejemplo de Ogre. Recuerda tener instalado el AppWizard, que crea unos templates, para crear proyectos ya configurados de Ogre en el VS2008.

Arrancamos el VS2008 y Nuevo Proyecto-> Aplicación Ogre -> Le damos un nombre Ej: Instalacion y lo dejamos en Standard Application. Tendremos nuestra primera aplicación en Ogre con esta estructura.


Estructura de primera Aplicación:

  • Header files
  • BaseApplication.h es la declaración de Clase, una estructura de la Clase BaseApplication.
  • Instalacion.h es la estructura de clase de nuestro codigo, hace herencia a BaseApplication
  • Resource.h son parametros de inicio de aplicación de Ogre y Ventanas.
  • Resource File
  • Instalacion.ico es el icono que aparecera arriba a la derecha en la ventana.
  • Instalacion.rc es un fichero de inicio de ventana, es solo de windows necesita el Resource.h y el Intalacion.ico para colocar el icono y psar variables. Utiliza codigo Delphi.
  • Source Files
  • BaseApplcation.cpp es la implementación del la clase BaseApplication, que explicaremos en los siguientes tutoriales.
  • Instalacion.cpp es la implementacion de la clase Instalacion.

Si pulsamos F5 compilaremos y ejecutaremos el codigo, y deberia salir lo siguiente:


En los siguientes tutoriales, explicaremos el codigo BaseApplication.cpp, cambiaremos el logo, y explicaremos lo mas basico de Nodos,escenas y Entity.