Inicio > OGRE 3D > Tutorial Básico # 2 Constructores Básicos de Ogre3D

Tutorial Básico # 2 Constructores Básicos de Ogre3D

En este pequeño tutorial estaré comentando sobre el uso de los constructores más básicos de Ogre3D, me refiero a los SceneManager (Gestor de Escena), SceneNode (Nodo de Escena) y Entity Objects (Objetos de Entidad). Quizás la traducción de los términos no sea la perfecta pero para los que no dominan el Inglés al menos se puedan  llevar la idea.

Antes de continuar quisiera aclarar que los tutoriales los estoy basando en los oficiales que se encuentran en la Wiki de Ogre3D. En el foro oficial de Ogre 3D los que desean hablar en español cuentan con muy pocas posibilidades ya que el contenido  está en un 99% en Inglés y las posibles dudas en español pueden quedar en el olvido. Es por eso que entre otras cosas me motivé a crear este espacio, para que al menos lo más básico pueda llegar a todos en su Idioma Nativo Español.  Como última aclaración quisiera decir que todo el código que se muestre en los tutoriales ha sido probado al 101% por mi, cualquier duda pueden dejar sus comentarios en el tutorial correspondiente.

Aclarado lo anterior, seguimos…

.

Prerequisitos:

.

Para poder completar satisfactoriamente el tutorial debes dominar el procedimiento para crear un nuevo proyecto basado en el asistente de aplicaciones de Ogre3d, si no sabes como hacer esto dale un vistazo al Tutorial #1 – Guía Paso a Paso para crear nuestra primera aplicación con Ogre3D.

.

Comenzando:

.

Crearemos un nuevo proyecto en nuestro Visual Studio 2008 al cual llamaremos Tutorial2, en las opciones del asistente seleccionaremos las mismas que en el tutorial anterior,  Standard Application y dejaremos marcada la opción Post Build Copy.


Con esto nuestro asistente nos habrá generado todos los archivos necesarios.

Es necesario aclarar que en este tutorial solamente estaremos trabajando con el archivo Tutorial2.cpp y con la función miembro createScene().

Veamos el código

Tutorial2.cpp

#include «Tutorial2.h»

//————————————————————————————-
Tutorial2::Tutorial2(void)
{
}
//————————————————————————————-
Tutorial2::~Tutorial2(void)
{
}

//————————————————————————————-
void Tutorial2::createScene(void)
{
Ogre::Entity* ogreHead = mSceneMgr->createEntity(«Head», «ogrehead.mesh»);

Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
headNode->attachObject(ogreHead);

// Set ambient light
mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));

// Create a light
Ogre::Light* l = mSceneMgr->createLight(«MainLight»);
l->setPosition(20,80,50);
}

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include «windows.h»
#endif

#ifdef __cplusplus
extern «C» {
#endif

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char *argv[])
#endif
{
// Create application object
Tutorial2 app;

try {
app.go();
} catch( Ogre::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().c_str() << std::endl;
#endif
}

return 0;
}

#ifdef __cplusplus
}
#endif

Para ganar un poco en claridad me he tomado la libertad de eliminar el código que automáticamente genera el asistente de aplicaciones, además le puse como color rojo a la función miembro con la que vamos a trabajar (createScene).

Si se desea se puede generar el proyecto para comprobar que no da errores.

.

Eliminando Código de Ejemplo

.

Una vez que haya ejecutado correctamente el programa debe eliminar el código que se encuentra dentro de la función createScene() pero no la función en si misma. Estaremos adicionando el código y examinándolo línea por línea.

Función createScene

void Tutorial2::createScene(void)
{

Ogre::Entity* ogreHead = mSceneMgr->createEntity(«Head», «ogrehead.mesh»);Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
headNode->attachObject(ogreHead);

// Set ambient light
mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));

// Create a light
Ogre::Light* l = mSceneMgr->createLight(«MainLight»);
l->setPosition(20,80,50);

}

Elimine el código que se muestra en color azul.

Con esto ya estamos listos para empezar a introducir código, pero antes un poco de teoría para saber de donde caen las cosas.

.

Estilo de trabajo de Ogre

.

Este es un tema bien amplio, empezaré con los SceneManagers y posteriormente con los Entities y los SceneNodes. Estas tres clases son fundamentales en las aplicaciones de Ogre.

Lo básico de los SceneManager(Gestor de Escena)

Todo lo que aparece en la pantalla es controlado por el SceneManager. Cuando se colocan los objetos en la escena, el SceneManager es la clase que realiza el siguimiento de los mismos. Por ejemplo cuando se crean cámaras para ver la escena el SceneManager realiza el siguimiento a la misma, al igual que con los planos, luces,…. etc.

Existen diferentes tipos de SceneManagers, algunos para renderizar terreno, otros para los mapas BSP (Mapas tipo Quake, Hall-Life y Call of Duty). En tutoriales posteriores nos adentraremos más en el uso de los  SceneManagers.

Lo básico de los Entity (Entidad)

Una Entidad es un tipo de objeto de los que puedes renderizar en una escena. Puedes pensar en una Entidad como cualquier cosa representada en una malla 3D (3D mesh), por ejemplo  una caja, la cabeza del ogro, un robot, etc. Las luces, cámaras, Partículas, etc no son entidades.

Algo para destacar en Ogre es que separa los objetos renderizables de su ubicación y orientación. Eso significa que no es posible colocar directamente una entidad en una escena, para eso se debe adjuntar la Entidad a un objeto tipo SceneNode y este será quien contenga la información sobre la ubicación y la orientación.

Lo básico de los SceneNode (Nodo de Escena)

Como ya mencioné, los Nodos de Escena realizan un seguimiento de la ubicación y orientación de todos los objetos adjuntos a él. Cuando se crea una Entidad esta no es renderizada en la escena a menos que que sea adjuntada a un Nodo de Escena. Vale aclarar que un Nodo de Escena no es un objeto que se muestra en la pantalla, solamente cuando se crea un Nodo de Escena y se le adjunta una Entidad es que se puede mostrar.

Los Nodos de Escena pueden tener cualqueir cantidad de objetos adjuntos. Digamos que tenemos un personaje caminando por la pantalla y se desea que genere una luz alrededor de el. La forma de hacer esto seria primeramente crear un Nodo de Escena, después crear una Entidad para el personaje y adjuntarlo al Nodo de Escena creado. Entonces creariamos un objetos de luz el cual adjuntariamos tambien al Nodo de Escena creado. Los Nodos de Escena pueden ser adjuntados a otros Nodos de Escena con lo que es posible crear jerarquías completas de nodos.

Algo a destacar acerca de los Nodos de Escena es que su posición siempre es relativa a Nodo Padre y que cada Gestor de Escena contiene un nodo raíz al cual todos los otros Nodos de Escena están adjuntos.

.

Su primera aplicación con Ogre3D

.

Regresando ahora al código que teniamos, buscamos nuestra función Tutorial2::createScene (que será en la que trabajaremos). Lo primero que haremos será crear una luz ambiental para poder ver lo que tenemos en la escena. Esto podemos hacerlo llamando a la función setAmbientLight y especificando el color que deseamos. Note que el constrctor del valor del color espera los valores para rojo, verde y azul en el rango de 0 a 1. Agregue esta línea a createScene:

void Tutorial2::createScene(void)
{

// Establecer luz ambiental (Esto es un comentario)
mSceneMgr->setAmbientLight(Ogre::ColourValue(1.0, 1.0, 1.0));

}

Con esto ya habremos creado nuestra luz ambiental para la escena, ahora crearemos nuestra primera entidad, lo cual podemos hacer llamando a la función miembro createEntity del SceneManager. Agregue estas líneas al código.

Ogre::Entity* ogreHead = mSceneMgr->createEntity(«Head», «ogrehead.mesh»);

A raíz del código anterior varias interrogantes pueden surgir. De donde sale el mSceneMgr y cuales son los parametros que estamos usando.

El mSceneMgr  es una variable que contiene al objeto SceneManager que se está utilizando, esto es hecho por nuestro asistente de aplicaciones. Por otra parte el Primer parámetro se refiere al nombre de la Entidad que estamos creando ( TODAS LAS ENTIDADES DEBEN TENER UN NOMBRE UNICO). El segundo parámetro especifica la malla que queremos  usar para la entidad. «ogrehead.mesh» es una malla que viene por defecto en el SDK de Ogre3D. La carga recursos la veremos en posteriores tutoriales, por ahora seguiremos usando las posibilidades de carga de nuestra aplicación generada mediante el asistente.

Ahora que hemos creado la entidad necesitamos crear un Nodo de Escena para adjuntarla.  Como cada Gestor de Escena tiene un Nodo de Escena raíz, crearemos un hijo de ese nodo.

Ogre::SceneNode* headNode =
mSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode");

Esta larga declaración primeramente llama a getRootSceneNode el SceneManager actual, que a su vez llama al métodp createChildSceneNode del SceneNode raíz. El parámetro para createChildSceneNode es el nombre del SceneNode que estamos creando. Al igual que la clase Entity, dos SceneNodes no pueden tener el mismo nombre.

Finalmente necesitamos adjuntar la Entidad al Nodo de Escena para dar la ubicación de renderizado. Esto lo hacemos de la siguiente manera.

headNode->attachObject(ogreHead);

Con esto ya hemos analizado línea por línea el contenido de nuestra función createScene. Su función debe mostrarse mas o menos así.

void Tutorial2::createScene(void)
{
//Creando Entidad y adjuntándola al Nodo de Escena

Ogre::Entity* ogreHead = mSceneMgr->createEntity(«Head», «ogrehead.mesh»);

Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
headNode->attachObject(ogreHead);

// Establecer luz ambiental
mSceneMgr->setAmbientLight(Ogre::ColourValue(1.0, 1.0, 1.0));

}

Ahora veamos algunos detalles extra.

.

Coordenadas y Vectores

.

Hablemos un poco de las coordenadas en pantalla de Ogre y sus vectores. Ogre utiliza los ejes X y Z para el plano horizontal y el eje Y para el vertical. Mirando el monitor de frente el eje X va del borde izquierdo( – ) al derecho ( + ), el eje Y de la parte inferior ( – ) a la superior ( + ) y el el eje Z viene desde de dentro del monitor( – ) hacia afuera ( + )

Note como la cabeza del ogro está mirando de frente al cargar la aplicación. Esto es una propiedad de la malla además de la posición y de el lugar que está mirando la cámara. Por ahora solo nos importa saber que la cabeza del Ogro está situada en la posición (0,0,0). La dirección de la Cabeza es el resultado de como la malla fue orientada cuando se creo por su diseñador.

Ogre no hace suposiciones acerca de cómo orientar a sus modelos. Cada malla que carga puede tener una diferente «dirección inicial» a la que esté mirando.

Ogre usa la clase vector para representar la posición y la dirección, existen vectores para diferentes dimensiones (Vector2, Vector3,Vector4) para dos, tres y cuatro dimensiones respectivamente, siendo el Vector3 el más utilizado.

.

Agregando otro Objeto

.

Ahora que ya sabemos como funciona el sistema de coordenadas regresemos a las tres líneas de código que escribimos. Como se puede apreciar nosotros no especificamos la posición inicial de la cabeza del ogro. La gran mayoría de las funciones en Ogre cuenta con parámetros por defecto, por ejemplo nuestra función en cuestión (SceneNode::createChildSceneNode) posee tres parámetros, el nombre de la escena, la orientación(a donde está mirando)y  la posición(que fue asignada para nosotros en (0,0,0)).Agreguemos entonces otro objeto pero esta vez especificaremos su posición inicial.

Ogre::Entity* ogreHead2 = mSceneMgr->createEntity( «Head2», «ogrehead.mesh» );
Ogre::SceneNode* headNode2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( «HeadNode2», Ogre::Vector3( 100, 0, 0 ) );
headNode2->attachObject( ogreHead2 );

Compile su proyecto y obtendrá algo como esto.

Como se puede apreciar el código es facilmente entendible, hicimos un procedimiento similar con la única diferencia que hemos llamado a la Entidad y al Nodo de Escena de una forma diferente y que hemos posicionado la posición inicial del segundo ogro unas 100 unidades a la derecha en el eje X.

Si al ejecutar el proyecto no ve las dos cabezas aleje la cámara mediante la teclas hasta que pueda verlas.

Hasta aquí por el momento, creo haber explicado basicamente el funcionamiento  de las Entidades, Nodos de Escena y Gestor de Escena. En el próximo tutorial estaré comentando sobre otras funciones para el trabajo con las entidades para rotarlas, escalarlas asi como el trabajo con los archivos de Configuración.

Desde Cuba un saludos de Cubansephiroth.

Si este tutorial te ha servido de alguna ayuda deja tu comentario a modo de agradecimiento.

Categorías: OGRE 3D Etiquetas:
  1. junio 22, 2010 a las 5:07 am

    Hola, tengo una lista en twitter de opengl-ogre3D. Ya te he incluido. El tutorial lo hojeo con calma después y te mando otro comentario. Un saludo.

  2. julio 29, 2010 a las 4:08 am

    hi! i am making cross engine game develope platform, welcome my website.

  3. octubre 4, 2010 a las 7:48 pm

    Hola, desde ayer he estado visitando tu sitio, y me parece genial que subas estos tutoriales, son muy buenos y me estan sirviendo de mucho, de antemanos gracias por lo tutos que sigas subiendo.

  4. Daviddagbx
    enero 7, 2011 a las 5:46 am

    Felicidades por el tutorial de OGRE se ve bastante interesante.

  5. Victor
    enero 21, 2011 a las 7:41 pm

    Esto es genial!! Me encanta como lo explicas, se entiende todo a la perfección.

    Muchas gracias por estas aportaciones!

  6. Crist
    marzo 29, 2011 a las 1:08 am

    muy bueno, gracias men me ayudo mucho.

  7. PacKo
    May 7, 2011 a las 11:49 pm

    Fantastico men!! Estoy siguiendo el tutorial desde cero y la verdad que está perfectamente redactado, mis felicitaciones. Sigue asi!

  1. junio 25, 2010 a las 7:48 pm

Deja un comentario