¡El Tutorial Básico 0! ,

Instalación de ogre entendida como => Elementos necesarios para empezar a hacer cosas

¿Sin esto de qué me sirve el resto?
OGRE es una librería, que es usada por otras aplicaciones(IDEs de programación) para que estos compilen la aplicación.
Es quizás lo que falta y no está nada claro esto ofusca a cualquiera tratar de buscar esta información, ni siquiera en ingles.

Entonces si sabemos que es una librería que no tiene entorno gráfico, ¿que tengo que instalar?

En linux, (en windows que lo haga otro).
Necesitas un IDE de programación, si dominas alguno o estás habituado este capítulo te lo saltas y punto (es para noobs).
¿Cuál IDE utilizo? Eclipse, Netbeans, mira que hay la leche de ellos.
Aquí es donde me pierdo, ya que sólo se que requiere que tenga capacidad de compilar .... (un formato, un lenguaje, una norma?)
Cada uno de ellos tiene sus propias configuraciones, pero si no, se lo que tengo que configurar, mal vamos.

Si consigues salvar ese obstáculo, el siguiente será mas sencillo, ya que es vincular tu IDE a las librerías, es decir, decirle que son parte. (una especie de plug-in, este paso requiere previa instalación de OGRE por lo de las rutas y otras cosas, pero lo omito porque instalar OGRE en linux es bastante sencillo).

Bien ya esta todo configurado. ¿y ahora?

Pues ahora, para empezar puedes iniciarte con los ejemplos. Ver como son y como trabajar con los ficheros.

Luego sigue con los tutos. porque ya tienes un entorno de trabajo. que es lo que faltaba.


Tutorial Básico 1

Una introducción a las construcciones mas básicas en Ogre: SceneManager, SceneNode, y objetos Entity.



Introducción del Tutorial

external image dl1773
En este tutorial te introduciremos en las construcciones mas básicas en Ogre: SceneManager, SceneNode, y Objetos Entity. No cubriremos una gran cantidad de código; en vez de esto nos centraremos en los conceptos generales para que empieces a aprender Ogre.

Como verás a lo largo del tutorial deberías añadir lentamente código a tu proyecto y mirar los resultados al compilarlo. No hay otra forma de familiarizarse con los conceptos! Resiste la tentación de sólo leerlo, practica.




external image help.gifAlgunos problemas que encontrarás mientras trabajas con este material deben estar comentados en el Foro de Ayuda.

Requisitos previos


  • Este tutorial asume que tienes conocimientos de programación en C++ y eres capaz de instalar y compilar una aplicación de Ogre.
  • Este tutorial también asume que has creado un proyecto usando el Tutorial Framework Ogre Wiki, manualmente, usando CMake o el AppWizard(Asistente de Aplicación) de Ogre - mirar Creando una Aplicación para más instrucciones.

Comenzando


Código Inicial


Hemos usado un código pre-construido como base para este tutorial. Deberías ignorar todas las excepciones de código que serán añadidas al método createScene. En un tutorial posterior explicaremos en profundidad como las aplicaciones de Ogre funcionan, pero por ahora estamos comenzando por el nivel mas básico.

Leer Creando una Aplicación para aprender a como crear el proyecto inicial y los archivos de fuentes para tu IDE y entorno particulares.

Crear un nombre de proyecto llamado Tutorial

Añade el tutorial de framework de aplicación a él:
BaseApplication.h
BaseApplication.cpp
TutorialApplication.h
TutorialApplication.cpp
Consigue los archivos de aquí: Tutorial Framework Ogre Wiki
o, usa el AppWizard de Ogre.

TutorialApplication.cpp es el único archivo que usaremos para este tutorial y solamente trabajará con la función miembro de createScene().

TutorialApplication.cpp debería contener el siguiente código. He eliminado solo los comentarios de cabecera para mantenerlo más legible.
#include "TutorialApplication.h"
 
TutorialApplication::TutorialApplication(void)
{
}
 
TutorialApplication::~TutorialApplication(void)
{
}
 
//-------------------------------------------------------------------------------------
void TutorialApplication::createScene(void)
{
    Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");
 
    Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    headNode->attachObject(ogreHead);
 
    // Establece la luz ambiental
    mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));
 
    // Crea una luz
    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
    {
        // Crea un objeto de aplicacion
        TutorialApplication 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

Ve más allá y compila y ejecuta este programa para asegurarte que tu entorno está ajustado correctamente. Una vez que el programa esté funcionando, usa las teclas WASD para moverte, y el ratón para mirar alrededor. La tecla Escape te permite salir del programa.

Problemas


Si tienes problemas, comprueba Creando una Aplicación para configurar tu compilador correctamente, o mira en el archivo Ogre.log para información más detallada. Si necesitas más ayuda, búscala en los foros. Seguro que tu problema ya ha ocurrido otras veces. Si no ha ocurrido antes, lee las reglas del foro y pregúntalo. Asegúrate de proporcionar detalles relevantes de tu Ogre.log, excepciones, mensajes de error, y trazados del depurador.

Nota que los últimos tutoriales no contendrán esta información de error, así que por favor pon atención a las siguientes secciones si estás teniendo problemas.

Problema de Message Box


Si estás usando Visual Studio con el soporte Unicode encendido en el proyecto se te presentará este error:
error C2664: 'MessageBoxW' : cannot convert parameter 2 from 'const char *' to 'LPCWSTR'
Los tipos apuntados están sin relacionar; la conversión necesita de reinterpret_cast, el estilo de casting de C o el estilo de casting de función.
El problema es que la función MessageBox está (en este caso) esperando Unicode, y le estamos dando una cadena ANSI. para arreglar esto, cambia la siguiente línea:
MessageBox( NULL, e.what(), "An exception has occured!", MB_OK | MB_IConerror | MB_TASKMODAL);

a esta:
MessageBoxA( NULL, e.what(), "An exception has occured!", MB_OK | MB_IConerror | MB_TASKMODAL);
O puedes cambiar tu formato de texto en el compilador de Unicode a ANSI.
Sin embargo, perderás el soporte para lenguajes internacionales.

La razón para esto es que "MessageBox" es automáticamente resuelto a MessageBoxA (ANSI) o MessageBoxW (Wide/Unicode), dependiendo de la configuración del proyecto. Arreglamos el error siendo explícitos sobre el usando ANSI.

Si falta el Archivo de Configuración o las DLLs


Si estas intentando lanzar la aplicación para compilarla de nuevo pero el programa adolece de DLLs o archivos de configuración (*.cfg), entonces probablemente no has copiado todos desde la carpeta del OgreSDK. En Visual Studio, cuando compilas tu aplicación en modo release, se pone la versión ejecutable release en la carpeta [CarpetaProyecto]\bin\release , y el ejecutable de debug en la carpeta [CarpetaProyecto]\bin\debug. Debes copiar todos los ".dll" y ".cfg" desde el OgreSDK a las carpetas apropiadas. Esto es, copiar los archivos desde [OgreSDK]\bin\release a [CarpetaProyecto]\bin\release y [OgreSDK]\bin\debug to [CarpetaProyecto]\bin\debug. También necesitas editar el archivo resources.cfg para que apunte a las rutas correctas. Mirar la siguiente sección para más información sobre esto.

Problemas de Recursos o Plugin


Asegúrate de que tienes los archivos plugins.cfg y resources.cfg en el mismo directorio que el ejecutable. Plugins.cfg le dice a OGRE que librerías de renderizado están disponibles (Direct3D9, OpenGL, etc). El Resource.cfg es usado por ExampleApplication y especifica las rutas a las texturas, mallas y scripts. Ambos son archivos de texto, asi que edítalos y asegúrate que las rutas sean correctas. De otra forma tu caja de diálogo de instalacion de Ogre no encontrar las librerías de renderizado, y recibirás un error por pantalla o en Ogre.log que se parecerá a esto:
Description: ../../Media/packs/OgreCore.zip - error whilst opening archive: Unable to read zip file
Si este es el caso, abre el fichero resources.cfg y cambia las rutas que contiene para que apunten a las localizaciones en la carpeta de Media que viene con Ogre. Nota que no puedes usar variables de entorno tales como $(AlgunaVariable) en estas rutas.

No se puede lanzar una Aplicación en Visual Studio o en Code::Blocks


Si estás usando Visual Studio o Visual C++ para crear la aplicación y estás teniendo problemas para lanzarlo desde el entorno, el problema se debe a los problemas sobre depuración. Si presionas el botón de reproducción (o vas al menú de comienzo de depurado) y consigues una excepción que dice que el archivo de configuración (*.cfg) no se puede encontrar, entonces el directorio de trabajo probablemente no se ha establecido.

Las instrucciones exactas para fijar esto variarán basándose en que versión de Visual C++ que estás usando, así que no te puedo dar un procedimiento directo, pero los pasos básicos deberían ser los mismos. Botón derecho en el proyecto en el explorador de soluciones (no la solución en si misma) e ir a propiedades. En algún lugar en las propiedades de configuración debería estar la opción para "Debugging". En las opciones de debugging deberia haber un campo de directorio de trabajo "Working Directory". Este debería ser establecido a la posición en la que el archivo ejecutable de tu proyecto esta colocado.

Si tienes problemas al usar esto, intenta imitar el campo "Command" que también estará en las opciones de debugging. Por ejemplo, en Visual C++ 2003, el campo "Command" debería ser similar a "..\..\bin\$(NombreConfiguracion)\$(NombreObjetivo)". Para el directorio de trabajo, necesitamos eliminar la porción del comando que es el nombre del objetivo (el ejecutable). En este caso, el directorio de trabajo deberia ser "..\..\bin\$(NombreConfiguracion)". La cadena exacta que tienes que poner aqui variara basándose en la versión de Visual C++ y en el entorno de compilación, asi que asegúrate de comprobar el campo Command antes de hacer esto. Asegúrate de cambiar el directorio de trabajo para ambas configuraciones de Release y Debug.

En Visual C++ 2005 probablemente sea algo diferente enteramente. He encontrado el directorio "..\..\bin\$(NombreConfiguracion)" como una buena forma de probar primero, si todavía no funciona tendrás que tocarlo algo, o consultar algo de ayuda en los foros de Ogre.

Si estas usando Code::Blocks entonces necesitas hacer lo mismo, por favor click derecho en tu proyecto y selecciona "Properties...", ahora ve a "Build Targets" entonces cambia el campo "Execution working dir:" al mismo directorio en el que has colocado el ejecutable de tu programa.

La razón que tenemos para hacer esto es que Ogre espera que ciertos archivos estén en el mismo directorio al igual que el ejecutable, y sin ajustar el directorio de trabajo con estos archivos, no funcionará.

Una vez que has ejecutado el programa correctamente, ve dentro del código y elimina la porción de codigo de dentro de la función createScene() pero no elimines la función en si misma. Colocaremos código en esta función y veremos como se comporta línea a línea.

Como funciona Ogre


Un tema directo. Comenzaremos con los SceneManagers (manejadores de escena) y trabajaremos a nuestro modo con Entidades y SceneNodes. Estas tres clases son los bloques fundamentales para la compilación de las aplicaciones de Ogre.

SceneManager lo básico


Cualquier cosa que aparece en pantalla esta manejada por el SceneManager. Cuando colocas objetos en la escena, el Scenemanager es la clase que guarda sus posiciones. Cuando creas cámaras para ver la escena (lo que cubriremos en otro tutorial) el SceneManager guarda pistas sobre ellos. Cuando creas planos, billboards, luces ... y demás, el SceneManager guarda datos de ellos.

Hay múltiples tipos de SceneManagers. Hay SceneManagers que renderizan terreno, hay un SceneManager para renderizado de mapas BSP, y demás. puedes ver los diversos tipos de SceneManagers listados aquí. Hablaremos más sobre los diversos SceneManagers según avancemos en los tutoriales.

Entidades lo básico


Una entidad es uno de los tipos de objeto que se pueden renderizar en una escena. Puedes pensar en una entidad como en una cosa que representa una malla en 3D. Un robot podría ser una entidad, un pez podría ser una entidad, el terreno sobre el cual tus personajes caminan también podria ser una entidad grande. Cosas como Luces, Billboards, Particulas , Cámaras, etc no pueden ser entidades.

Una cosa a notar sobre Ogre es que separa objetos renderizables por su posición y orientación. Esto significa que no puedes colocar directamente una Entidad en una escena. En vez de eso debes acoplar la Entity al objeto SceneNode, y este SceneNode contiene la información sobre la posición y orientación.

SceneNode lo básico


Como ya he mencionado, las SceneNodes guardan la posición y orientación para todos los objetos acoplados. Cuando creas una Entidad, no se renderizará en una escena hasta que lo acoples a un SceneNode. Además, un SceneNode no es un objeto que puede ser mostrado en la pantalla. Sólo cuando creas un SceneNode y le acoplas una Entidad (u otro objeto) esto se puede mostrar sobre una pantalla.

Los SceneNodes pueden tener cualquier número de objetos acoplados a ellos. Déjame decirte que tienes un personaje caminando alrededor de la pantalla y quieres tener una luz generada alrededor de él. El modo para hacer esto podría ser primero crear un SceneNode, entonces crear una Entidad para el personaje y acoplarlo a la SceneNode. entonces podrías crear un objeto Light y acoplarlo al SceneNode. Los Scenenodes podrían también ser acoplados a otros SceneNodes que te permitirían crear jerarquias enteras de nodos. Explicaremos usos mas avanzados del acoplado de SceneNode en otros tutoriales.

Un concepto mayor que tienes que tener en cuenta sobre SceneNodes es que la posicion de un SceneNode es siempre relativa a su SceneNode padre, y cada SceneManager contiene un nodo raíz (root) al cual todos los otros SceneNodes están acoplados.

Tu primera aplicación con Ogre


Ahora ve al código que creamos antes. Encuentra la funcion TutorialApplication::createScene. Sólo manipularemos los contenidos de esta función en este tutorial. La primera cosa que queremos hacer es establecer la luz de ambiente para la escena así que podemos ver que estamos haciendo. Podemos hacer esto llamando a la función setAmbientLight y especificando que color queremos. Nota que el constructor ColourValue espera valores para rojo, verde y azul en el rango entre 0 y 1. Añadir esta línea a createScene:
mSceneMgr->setAmbientLight(Ogre::ColourValue(1.0, 1.0, 1.0));
La siguiente cosa que necesitaremos hacer es crear una Entity. Haremos esto llamando a la función miembro createEntity del SceneManager:
Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");
Ok, varias cuestiones deberían llamarnos la atención. Lo primero de todo, de donde viene mSceneMgr, y con que parámetros debemos llamar a esta función? la variable mSceneMgr contiene el objeto actual SceneManager (este es realizado para nosotros por la clase BaseApplication). El primer parametro para createEntity es el nombre del Entity que hemos creado. Todas las entidades deben tener un nombre único. conseguirás un error si intentar crear entidades con el mismo nombre. El parámetro "ogrehead.mesh" especifica la malla que queremos usar para la Entity. "ogrehead.mesh" es un recurso que viene con el Ogre SDK. La carga de recursos será cubierta en un tutorial posterior como las mallas. Por ahora estamos usando las capacidades de carga de recursos de la clase BaseApplication.

Ahora que hemos creado la Entity, necesitamos crear un SceneNode para acoplarlo. Hasta que cada SceneManager tenga una raíz SceneNode, tendremos que crear un hijo de este nodo:
Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode");
Esta gran sentencia llama primero a getRootSceneNode del SceneManager actual. Entonces llama al método createChildSceneNode de la raíz SceneNode. El parámetro para createChildSceneNode es el nombre de la SceneNode que estamos creando. Como la clase Entity, dos SceneNodes no pueden tener el mismo nombre.

Finalmente, podemos necesitar acoplar la Entity al SceneNode para dar a la cabeza del ogro una posición de renderizado:
headNode->attachObject(ogreHead);
ya está! Compila y ejecuta tu aplicación. Deberás ver una cabeza de ogro en la pantalla.

Coordenadas y Vectores


Antes de que siguas, necesitamos hablar sobre las coordenadas de pantalla y los objetos Vector. Ogre (como muchos otros motores de gráficos) usa los ejes x y z como el plano horizontal, y el eje y como el plano vertical. Como ves en el monitor ahora, el eje x deberá desplazarse de izquierda a derecha en tu monitor, con la parte derecha apuntando en la dirección x positiva. El eje y debería ejecutarse desde abajo del monitor hasta arriba del monitor, siendo la parte superior la dirección positiva del eje y. El eje z debería correr dentro y fuera de tu pantalla, con la salida de la pantalla estando en la dirección z positiva.

external image display1921

El sistema de coordenadas Cartesianas en la pantalla del ordenador

Date cuenta como nuestra cabeza de Ogro tiene su cara apuntada a lo largo de la dirección -x? Esto es una propiedad de la malla y la posición de la cámara y las caras. Las cámaras se explicarán en un tutorial posterior pero por ahora sólo reconoce que la cabeza del ogro está posicionada en la posición (0,0,0) y nuestra vista de ella esta enfrente. La dirección en que la cara de la cabeza se apunta es el resultado de como la malla fue orientada cuando fue creada y salvada por el artista. Ogre no presupone como orientas tus modelos. Cada malla que cargas tiene una dirección diferente de comienzo a la cual se orienta.

Ogre usa la clase Vector para representar ambas posición y dirección (no hay clase Point). Hay vectores definidos para 2 (Vector2), 3 (Vector3), y 4 (Vector4) dimensiones, el Vector3 será el más comúnmente usado. Si no estás familiarizado con Vectores, sugiero que los estudies antes de hacer cualquier cosa seria con Ogre. La matemática detrás de los Vectores será muy importante y útil cuando comiences a trabajar con programas complejos.

Añadiendo otro Objeto


Ahora que comprendes como funcionan los sistemas de coordenadas, podemos volver a nuestro código. En las tres líneas que escribimos, queremos especificar la posición exacta donde queremos que nuestra cabeza de ogro aparezca. La gran mayoría de las funciones en ogre tienen parámetros por defecto para ellas. Por ejemplo, el miembro de función SceneNode::createChildSceneNode en Ogre tiene tres parámetros: el nombre del SceneNode, la posición del SceneNode, y la rotación inicial (orientación) de las caras del SceneNode. La posición, como puedes ver ha sido establecida por nosotros a las coordenadas (0,0,0). Crea otro SceneNode, pero esta vez especificaremos el punto de comienzo que no sera otro que el origen:
Ogre::Entity* ogreHead2 = mSceneMgr->createEntity( "Head2", "ogrehead.mesh" );
Ogre::SceneNode* headNode2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "HeadNode2", Ogre::Vector3( 100, 0, 0 ) );
headNode2->attachObject( ogreHead2 );
Esto debería sernos familiar. Tenemos que hacer exactamente lo mismo que antes, con dos excepciones. Lo primero de todo, tenemos que nombrar la Entity y la SceneNode de forma diferente. La segunda cosa, tenemos que hacer esto especificando la posición de comienzo a 100 unidades en la dirección x desde la raíz del SceneNode (recuerda que todas las posiciones de SceneNode son relativas a sus padres). Compila y ejecuta el demo. Ahora hay dos cabezas de ogro una frente a otra. Deberías moverte atrás usando la tecla "s" o pulsado la flecha abajo para ver ambas cabezas.

Entidades más en profundidad


La clase Entidad es muy extensible, y no se explicará como usar cada porción del objeto ahora... sólo lo suficiente como para continuar. Hay unos pocos miembros de función utiles en la Entity que nos gustaría apuntarte.

Los primeros son Entity::setVisible y Entity::isVisible. Puedes establecer cualquier Entidad para que sea visible o no, simplemente llamando a esta función. Si necesitas ocultar una Entity, pero más tarde quieres mostrarla, entonces llama a esta función en lugar de destruir la Entity y luego recrearla. Nota que no necesitas "pool" Entidades. Sólo una copia de cualquier objeto de malla y textura se carga en memoria, asi que no tienes que preocuparte por como se salvan. La única cosa que tienes realmente que evitar son los costes de creacion y destruccion para el objeto Entity en si mismo, los cuales son relativamente bajos.

La función getName devuelve el nombre de la Entity, y la función getParentSceneNode devuelve el SceneNode al que la Entity está acoplada.

SceneNodes más en profundidad


La clase SceneNode es muy compleja. Hay muchas cosas que se pueden hacer con un SceneNode, asi que sólo cubriremos algunas de las más útiles.

Puedes coger y establecer la posición de un SceneNode con getPosition y setPosition (siempre en relación al SceneNode padre). Puedes mover el objeto de forma relativa a su posición actual usando el método de traslación.

Los SceneNodes no sólo establecen su posición, ellos también manejan la escala y rotación del objeto. Puedes establecer la escala de un objeto con la función scale. Puedes usar las funciones de pitch, yaw, y roll para rotar los objetos. Puedes usar resetOrientation para resetear todas las rotaciones hechas al objeto. También puedes usar las funciones setOrientation, getOrientation, y rotate para rotaciones más avanzadas. No hablaremos de Quaterniones hasta un tutorial más avanzado.

Ya has visto la función attachObject. Sus funciones relacionadas son útiles si quieres manipular los objetos que están acoplados al SceneNode: numAttachedObjects, getAttachedObject (hay múltiples versiones de esta función), detachObject (también múltiples versiones), detachAllObjects. Hay también todo un conjunto de funciones para tratar con SceneNodes padres e hijos.

Ya que todas las posiciones y traslaciones se hacen relativas al SceneNode padre, podemos hacer que dos SceneNodes se muevan juntos muy facilmente. Ya tenemos este código en la aplicación:
mSceneMgr->setAmbientLight(Ogre::ColourValue(1.0, 1.0, 1.0));
 
Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");
Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode");
headNode->attachObject(ogreHead);
 
Ogre::Entity* ogreHead2 = mSceneMgr->createEntity( "Head2", "ogrehead.mesh" );
Ogre::SceneNode* headNode2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "HeadNode2", Ogre::Vector3( 100, 0, 0 ) );
headNode2->attachObject( ogreHead2 );
Si cambiamos la sexta línea de esto:
Ogre::SceneNode* headNode2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "HeadNode2", Ogre::Vector3( 100, 0, 0 ) );
a esto:
Ogre::SceneNode* headNode2 = headNode->createChildSceneNode( "HeadNode2", Ogre::Vector3( 100, 0, 0 ) );
Entonces habremos hecho que headNode2 sea un hijo de headnode. Si movemos headNode moveremos neadNode2 también, pero moviendo headNode2 no se moverá headNode. Por ejemplo este código podría mover sólo headNode2:
headNode2->translate( Ogre::Vector3( 10, 0, 10 ) );
El siguiente código podría mover headNode, y ya que headNode2 es un hijo de headNode, headNode2 se movería también:
headNode->translate( Ogre::Vector3( 25, 0, 0 ) );
Si tienes problemas con esto, la cosa más fácil es comenzar en la raiz del SceneNode e ir bajando. Veamos (como en este caso), como comenzamos con headNode y (0,0,0) y lo trasladamos con (25,0,0), ahora la posición del headNode será (25,0,0) teniendo como referencia a su padre (desde su). headNode2 comienza en (100, 0, 0) y lo trasladamos mediante (10, 0, 10), así su nueva posición es (110, 0, 10) de manera relativa a su padre.

Ahora miremos a la figura, para ver donde están las cosas realmente. Comenzando en la raíz del SceneNode. Su posición siempre es (0,0,0). Ahora, la posición del nodo1 es (root + headNode): (0, 0, 0) + (25, 0, 0) = (25, 0, 0). Nada sorprendente. Ahora, headNode2 es un hijo del node1, asi que su posición es (root + headNode + headNode2) : (0, 0, 0) + (25, 0, 0) + (110, 0, 10). Esto es sólo un ejemplo para explicar como pensar sobre la herencia de la posición en el SceneNode. Rara vez necesitarás calcular la posición absoluta de tus nodos.

Finalmente, nota que puedes conseguir ambos SceneNodes y Entities por su nombre llamando a los métodos getSceneNode y getEntity del SceneManager, asi que no tendrás que guardar un puntero a cada SceneNode que crees. Deberías colgarte a uno cuando los uses a menudo.

Cosas a Probar


Por ahora deberías tener una noción básica sobre las Entidades (Entities), SceneNodes, y el SceneManager. Te sugiero que comiences con el código de abajo y añadas y elimines cabezas de Ogro desde la escena. Una vez que hayas hecho eso, limpia todos los métodos con el método createScene, y juega con cada uno de siguientes códigos de segmento:

Scale (Escalar)


Puedes usar para escalar la malla el método scale en SceneNode. Intentando cambiar los valores en la escala y viendo que consigues:
mSceneMgr->setAmbientLight(Ogre::ColourValue(1.0, 1.0, 1.0));
 
Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");
Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode");
headNode->attachObject(ogreHead);
 
headNode->scale( .5, 1, 2 );
 
Ogre::Entity* ogreHead2 = mSceneMgr->createEntity( "Head2", "ogrehead.mesh" );
Ogre::SceneNode* headNode2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "HeadNode2", Ogre::Vector3( 100, 0, 0 ) );
headNode2->attachObject( ogreHead2 );
 
headNode2->scale( 1, 2, 1 );

external image YawPitchRoll_5b_200px.png


Rotaciones


Puedes rotar el objeto usando los métodos yaw, pitch, y roll usando los objetos Degree o Radian. Pitch es la rotación alrededor del eje x, yaw es alrededor del eje y, y roll alrededor del eje z. Usando tu mano derecha como guía: apunta tu dedo gordo en dirección de un eje, y retrae los dedos restantes. La dirección indicada por la retracción coincidirá con la rotación positiva alrededor de ese eje:

external image dl1636&display&x=61&y=118

Intenta cambiar la cantidad de Degree (grados) y combina múltiples transformaciones:
mSceneMgr->setAmbientLight(Ogre::ColourValue(1.0, 1.0, 1.0));
 
Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");
Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode");
headNode->attachObject(ogreHead);
 
headNode->yaw( Ogre::Degree( -90 ) );
 
Ogre::Entity* ogreHead2 = mSceneMgr->createEntity( "Head2", "ogrehead.mesh" );
Ogre::SceneNode* headNode2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "HeadNode2", Ogre::Vector3( 100, 0, 0 ) );
headNode2->attachObject( ogreHead2 );
 
headNode2->pitch( Ogre::Degree( -90 ) );
 
Ogre::Entity* ogreHead3 = mSceneMgr->createEntity( "Head3", "ogrehead.mesh" );
Ogre::SceneNode* headNode3 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "HeadNode3", Ogre::Vector3( 200, 0, 0 ) );
headNode3->attachObject( ogreHead3 );
 
headNode3->roll( Ogre::Degree( -90 ) );
En Microsoft Visual Studio 2010, puede ocurrir un problema ya que "Degree" es un identificador no declarado.
Esto se puede arreglar llamando a la función como "Ogre::Degree", permitiendo la compilación con rotación.

El entorno de Ogre


La mayoría de los archivos (.DLL y .CFG) referenciados en esta sección (y a través de los tutoriales) pueden ser encontrados en la carpeta "bin" del OgreSDK bajo debug o release. Los programas de Debug que crees deberían usar archivos en la carpeta debug del OgreSDK, y los programas release deberían usar los archivos en la carpeta release.

Nota que mucho de esta sección trata sobre asuntos específicos de Windows. Bajo Linux es básicamente lo mismo, pero las librerías compartidas terminan en .so y residen en otra posición, y algunas cosas pueden ser diferentes. Si tienes problemas, asegúrate de preguntar en los foros de ayuda.

DLLs y Plugins


Ahora que hemos jugado con el entorno de Ogre un poquito, me gustaría explicarte como funciona la librería de Ogre en general para hacerte la vida más fácil cuando trabajas con él.

Ogre esta dividido en 3 grandes grupos de librerías compartidas: la librería main, la de plugins, y las librerías de terceros.

La Librería Main


El primer grupo consiste de la librería en si misma y las librerías compartidas de esta. La librería de Ogre esta contenida, completamente en OgreMain.dll. Este dll necesita de unas pocas librerías como cg.dll. Estas DLLs deben estar incluidas con cada aplicación de Ogre sin excepción.

Librerías de Plugins


El segundo grupo de librerías compartidas son los plugins. Ogre deposita gran parte de su funcionalidad en las librerías compartidas asi que pueden ser apagadas o encendidas dependiendo de las necesidades de tu aplicación. Los plugins básicos incluidos con Ogre tienen nombres de archivos que comienzan con el prefijo "Plugin_". Puedes crear nuevos plugins por ti mismo si tu aplicación los necesita, pero no podemos cubrir esto en un tutorial. Ogre también usa plugins para los sistemas de renderizado (tales como OpenGL, DirectX, etc). Estos plugins comienzan con el prefijo "RenderSystem_". Estos plugins existen asi que puedes añadir o eliminar sistemas de renderizado desde tu aplicación. Esto puede ser especialmente útil si escribes sombreadores o algo especifico para OpenGL (por ejemplo) y necesitas apagar la habilidad para correr el programa en DirectX, puedes simplemente eliminar el plugin del RenderSystem apropiado y no estará disponible. Además si tienes como objetivo una plataforma que no es estándar, puedes escribir tu propio plugin de RenderSystem, esto no se explicará en este tutorial. Explicaremos como eliminar plugins en la siguiente sección.

Librerías de terceros y Librerías de ayuda


El tercer grupo de librerías compartidas son las librerías de terceros y las librerías de ayuda. Ogre por si mismo es sólo una librería de renderizado de gráficos. No incluye cosas como sistemas GUI, control de la entrada, motores físicos, y demás. Tendremos que usar otras librerías para hacer estas cosas.

Las demos de Ogre y el SDK incluyen algunas de estas librerías de terceros y de ayuda. Entrada desde teclado y ratón a través de OIS (como sistema de entrada). Este está en OIS.dll.
Cg (C para gráficos) es usado por el CgProgramManager, y está contenido en Cg.dll.
Hay también otras librerías (no incluidas con el SDK) que te dan más funcionalidad (tales como sonido y física) sobre las que se puede encontrar mas información en otros lugares como son en los Wiki y en los foros.

La moraleja de la historia


La moraleja de la historia es que cuando estas probando tu aplicación localmente, puedes dejar todo "encendido" (esto es, no eliminar nada) para comprobarlo.
Cuando estas listo para distribuirlo, necesitas compilarlo en modo Release, e incluir todas estas DLLs de release que usa tu aplicación, y deberías eliminar las DLLs que no se usan.
Si tu programa no usa el Cg ProgramManager pero usa OIS, entonces no deberías incluir el Cg y las DLLs de CgProgramManager, pero debes incluir la dll de OIS o la aplicación no funcionará.

Archivos de configuración


Ogre depende de varios archivos de configuración. Estos controlan que plugins se cargan, donde estan los recursos de la aplicación, y demás. Haremos un resumen de lo que podemos encontrar en los archivos de configuración y que función tienen. Si tienes preguntas más especificas, deberías acudir directamente a los foros de ayuda.

plugins.cfg este archivo contiene los plugins que tu aplicación utiliza. Si quieres añadir o eliminar un plugin en la aplicación, necesitarás modificar este archivo. Para eliminar un plugin, o simplemente eliminar la línea apropiada, o comentarla poniendo un # al comienzo de línea. Para añadir un plugin, necesitarás añadir una línea como "Plugin=[NombrePlugin]". Nota que no pones todos los .DLL al final del nombre del plugin. Tu Plugin también no tiene que comenzar con "RenderSystem_" o "Plugin_". También puedes definir la posición en la que Ogre busca los plugins cambiando la variable "PluginFolder". Puedes usar ambas rutas absolutas o relativas, pero no puedes usar variables de entorno como $(CualquierVariable).

resources.cfg Este archivo contiene una lista de los directorios en los que ogre busca los recursos. Los recursos incluyen scripts, mallas, texturas, y demás. También puedes usar ambas rutas absolutas y relativas, pero no puedes usar variables de entorno como $(CualquierVariable). Nota que Ogre no buscará en subcarpetas, asi que debes introducirlas manualmente si tienes múltiples niveles. Por ejemplo, si tienes un árbol de directorio como "res\meshes" y "res\meshes\small", tendrás que añadir dos entradas al archivo resources conteniendo ambas rutas.

media.cfg Este archivo le da a Ogre información más detallada sobre algunos de los recursos. No se necesita a menos que necesites modificar este archivo alguna vez, asi me saltaré los detalles. Para más información puedes mirar en el Manual y en los foros de Ogre.

ogre.cfg Este archivo es generado por la pantalla de configuración de Ogre. Este archivo es específico de tu ordenador y de tu configuración gráfica. No deberías distribuir este archivo a otra gente cuando compartas tu aplicación, ya que ellos tendrán ajustes diferentes. Date cuenta de que no deberías editar este archivo directamente, en vez de esto usa la pantalla de configuración.

quake3settings.cfg Este archivo es usado con el BSPSceneManager. No necesitarás este archivo a menos que estes usando este manejador de escena (que no estas usando aquí), asi que ignoralo. No deberías distribuir este archivo con tu aplicación a menos, otra vez, que estes usando el BSPSceneManager, e incluso este será completamente diferente dependiendo de las necesidades de tu programa.

Estos son todos los archivos de configuración que Ogre manipula directamente. Ogre debe ser capaz de encontrar "plugins.cfg", "resources.cfg", y "media.cfg" para ejecutarse correctamente. En un tutorial posterior hablaremos más sobre estos archivos y como cambiar su posición y manipularlos para realizar cosas más avanzadas.

Conclusión


Llegados a este punto deberías tener una visión muy básica de las clases SceneManager, SceneNode, y Entity. No tienes que estar familiarizado con todas las funciones que he explicado. ya que estos al ser los objetos más básicos, se usarán muy frecuentemente. Te familiarizaras con ellos después de trabajar en los siguientes tutoriales.

Deberías familiarizarte con los ajustes del entorno de Ogre en los proyectos.

Siguiente Tutorial Básico 2 Cámaras, Luces, y Sombras