Ogre

Ogre
Ogre

Versiones:
Versión 1.7.0 (Cthugha)



OGRE. (acrónimo del inglés Object-Oriented Graphics Rendering Engine)Es un motor de renderizado Gráfico orientado a objetos, escrito en el lenguaje de programación C++.

Sus bibliotecas evitan la dificultad de la utilización de capas inferiores de librerías gráficas como OpenGL y DirectX, y además, proveen una interfaz basada en objetos del mundo y otras clases de alto nivel.

El motor es software libre, licenciado bajo MIT y con una comunidad muy activa. Incluso ha sido utilizado en algunos videojuegos comerciales, como por ejemplo Ankh y Earth Eternal.

Estructura de Ogre

La idea de engine 3D es proveer una manera fácil y rápida de dibujar las cosas en pantalla, ahorrandose todos los pasos de cofiguración de APIs de más bajo nivel como DirectX o OpenGL. Gracias a la estructura de Ogre, esto es muy sencillo.

Para comenzar, existen 3 elementos básicos y fundamentales en Ogre. Los SceneManagers, los SceneNodes y las Entitys.Las Entitys representan todas las cosas que pueden dibujarse en la pantalla. Ya sea un auto o un robot o lo que sea, todas esas cosas son Entitys. No son entidades por ejemplo las luces, las camaras, etc.Podemos ver a las Entitys como la abstracción que representa a un objeto pantalla.

Algo que cabe mencionar es que la la orientación y la ubicación de la Entity no son características de ella. Esas características son manejadas en otra estructura, los SceneNodes, que están especialmente diseñados para realizar estas tareas.

Por lo tanto, la única forma de modificar las características espaciales de una Entity es agregándolo a un SceneNode.

La clase Entity es muy grande y compleja y los detalles de cada uno de sus metodos pueden revisarlos en la documentación de Ogre o en los tutoriales.

Los SceneNodes son los que se encargan de las características de las Entitys. Los SceneNodes no son una cosa que se dibuje en pantalla, sino que lo único que hace es ser una especie de contenedor de Entidades y otras cosas útiles como cámaras o luces.

Los SceneNodes tambien ser padres de otros Scenenodes, con lo que se puede formar una jerarquía de nodos. Cabe mencionar que las posiciones de los SceneNodes son relativas a las de sus padres. De esta forma, si un nodo llamado NodoB, que tiene la posicion (3,0,0) y su padre, llamado NodoA que es el nodo raiz y que por lo tanto tiene sus coordenadas en escala absoluta, tiene la posición (2,0,0), la ubicación absoluta del NodoB será la (5,0,0).

Por último, los SceneManagers son los encargados de seguirle la pista a todas las cosas que se dibujan en la pantalla. Pueden verse tambien como el encargado de todo lo que tenga que ver on el dibujo del mundo. Poseen el nodo raíz de la jerarquía de SceneNodes, de forma que a partir de él se puede llegar a cualquier Entity en la pantalla.

Los SceneManagers son los encargados de el dibujo del terreno, por lo que en él se pueden especificar las características del mundo que se dibujara. Por ejemplo, si se va a realizar un juego de interiores, el SceneManager para ellos es distino que el para un juego de exteriores.

Desde el punto de vista de los patrones en Ing. de Software, los SceneManagers son fábricas de todos los elementos de una escena.

Características fundamentales

Cámaras

La cámara es lo que se usa en OGRE para ver la escena que se haya creado. La cámara es un objeto similar a un SceneNode, ya que también tiene métodos setPosition, yaw, pitch y roll, y la idea es adjuntar la cámara a un SceneNode. La idea por ahora es usar solo una cámara a la vez.
Para crear una cámara se hace: Camera* mCamera;
mCamera = mSceneMgr->createCamera("Camara1");
Uno también puede obtener una cámara ya creada según su nombre:
mCamera = mSceneMgr->getCamera("CamaraYaCreada");
Recordar que se debe adjuntar la cámara a un SceneNode, por lo que las posiciones de ésta serán relativas al nodo al que está adjunta. Para setear su posición se hace igual que con los nodos:
mCamera->setPosition(Vector3(0,100,50));
mCamera_>lookAt(Vector3(0,0,0));
El método lookAt sirve para asignar una dirección a la cámara sin tener que lidiar con los ángulos. Con ello se hace a la cámara apuntar a la posición que se le indica. (Recordar que las posiciones son relativas a quién está adjunta la cámara)
Tambien podemos setear los clippings de la cámara, que son las distancias mínima y máxima que se dibujarán en pantalla.
mCamera->setNearClipDistance(5);
mCamera->setFarClipDistance(80000);
Hay que notar que NO se debe setear una FarClipDistance si se van a usar Stencil Shadows.

Viewports

Los viewports son "cosas" que se asocian a una cámara y hacen que se vea lo que la cámara muestra. Por ejemplo, para juegos de carreras de 2 players, se pueden crear 2 viweports con 2 cámaras, uno para cada vista de cada player y se muestran las vistas de ambos players en la pantalla dividida en 2.
Por ahora puede ser útil manejar un viewport para cosas como la niebla comov eremos mas adelante.
Para crear un viewport:
Viewport* vp = mWindow->addViewport(mCamera);
Poner color al viewport:
vp->setBackgroundColour(ColourValue( 0,0,0));
Los colores ColourValue se indican con números decimales entre 0 y 1 indicando la cantidad de rojo, verde y azul que tendrá el color resultante. Esto de los colores del viewport es útil ya que cuando se pone niebla el color de ésta es ni mas ni menos que el color del viewport.

Luces y Sombras

Para usar sombras en OGRE (referido a las sombras que PROYECTAN los objetos sobre otros y sobre el terreno, no al sombreado de la superficie de los objetos) primero debemos elegir una técnica de sombreado. Esto se hace:
mSceneMgr->setShadowTechnique( SHADOWTYPE_STENCIL_MODULATIVE );
Hay 3 tipos de sombreados disponibles:
SHADOWTYPE_TEXTURE_MODULATIVE -> liviano pero horrible.
SHADOWYPE_STENCIL_MODULATIVE -> mas pesado pero bastante decente.
SHADOWTYPE_STENCIL_ADDITIVE -> Pesadísimo pero mas bonito.
Con los 2 últimos tipos de sombreado no se puede usar el far clipping. Finalmente, para usar las sombras necesitamos una luz ambiental:
mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ) ); //luz blanca muy clara
... y necesitamos indicar a una entidad (cuando se crea) si llama a sombras o no. (Si uno no quiere que un objeto proyecte sombras, por ejemplo, se le dice que no lo haga) Ejemplo:
Entity* ent = mSceneMgr->createEntity( "Ninja", "ninja.mesh" );
ent->setCastShadows( true ); //con false no llamaría sombras

Luces

Además de la luz ambiental, podemos crear focos de luz locales. El Punto de luz (LT_POINT) emite luz en todas direcciones. El LT_SPOTLIGHT es como un haz de luz en una dirección. Mientras que el LT_DIRECTIONAL es una luz como ambiental pero en una dirección (no se ve de donde se emite).
Por ejemplo, para crear una luz puntual:
Light* light = mSceneMgr->createLight( "Luz1" );
light->setType( Light::LT_POINT );
light->setPosition( Vector3(0, 150, 250) ); //también relativa al nodo al que se adjunta.
Debemos ponerle un color a la luz, en este caso será roja:
light->setDiffuseColour( 1.0, 0.0, 0.0 );
light->setSpecularColour( 1.0, 0.0, 0.0 );
NOTA: La luz en sí no se ve en pantalla, sino se ve cuando refleja en algún objeto cercano. Uno puede poner una imagen de una esfera roja en el centro de la luz por ejemplo, para que pareciera que la esfera emite esa luz...

Terrenos, Cielos y Niebla

Lo primero que debemos hacer es indicar al Scene Manager (al crearlo) que vamos a manejar terrenos:
mSceneMgr = mRoot->getSceneManager( ST_EXTERIOR_CLOSE ); //ese tipo de Scene Manager es para exteriores con terreno OGRE tare de muestra un terreno para probar. Lo usaremos como ejemplo.
mSceneMgr->setWorldGeometry( "terrain.cfg" );
Es un terreno básico que ocupa un mapa de alturas (heightmap) para dibujar un terreno con relieves.

Cielo

Para mostrar cielos en OGRE pueden usarse los SkyBoxes (una caja que rodea a la escena mostrando un cielo por todas partes, ideal para naves en el espacio y cosas así), los SkyDomes (media esfera que muestra un cielo mas natural pero solo arriba, ideal para exteriores con terreno) y los SkyPlanes (un plano puesto arriba que muestar cielo, suena raro pero funciona bien en FPS o cosas con terreno en que no se ve mucho el horizonte, o con niebla).
Los cielos son difíciles de crear, así que conviene usar los que vienen de muestra en OGRE o editarlos en su defecto. Para poner un SkyBox se usa:
mSceneMgr->setSkyBox( true, "Examples/SpaceSkyBox" ); En los tutoriales de OGRE se explica en detalle el uso de los cielos

Niebla

Hay 3 tipos de niebla en OGRE: una lineal y dos exponenciales.
Para una niebla lineal se hace por ejemplo:
mSceneMgr->setFog( FOG_LINEAR, ColourValue(0.3, 0.6, 1), 0.0, 2000, 5000 );
... lo que hace que aparezca niebla desde las 2000 unidades de distancia de la cámara y se vaya espesando hasta las 5000 unidades de distancia donde alcanza su máximo espesor del color indicado en el 2do parámetro. La idea es que ese color sea igual al color del viweport ya que pasado el final de la niebla (5000 unidades en este caso) lo que se ve es el color del viewport. Si es el mismo color da la sensación de niebla profunda hasta el horizonte.
La niebla exponencial es mas densa que la lineal, y la exponencial 2 aún mas densa!
mSceneMgr->setFog( FOG_EXP, ColourValue( 0, 0.5, 1), 0.005 );
mSceneMgr->setFog( FOG_EXP2, ColourValue( 0.3, 0.7, 0.2), 0.003 );

Animación

Las animaciones son muy fáciles de manejar en OGRE, lo difícil es hacerlas. Para hacerlas se pueden usar programas como el 3D Studio MAX junto con el OGRE Importer para 3DS MAX (disponible en la página de OGRE), pero es algo complejo. OGRE provee algunos meshes con animación como los robots.También se pueden encontrar en internet algunas. Para usar una animación debemos tener un mesh cargado a una entidad que tenga animaciones (como los robots de OGRE). Por ejemplo, si el robot tiene una animación llamada "Idle" en la que está sin hacer nada pero moviéndose ligeramente, podemos hacer que lo haga así:
AnimationState* mAnimationState = ent->getAnimationState( "Idle" ); //obtenemos una animacion
mAnimationState->setLoop( true ); //hacemos que se repita constantemente
mAnimationState->setEnabled( true ); //y finalmente le decimos que se ejecute
Las animaciones NO AVANZAN SOLAS, hay que hacerlas avanzar a cara frame:
mAnimationState->addTime( evt.timeSinceLastFrame );
Con esto le decimos a la animación que avance la cantidad de tiempo que transcurrió desde el último frame.
Además de "Idle", los robots poseen mas animacioens como "Die", "Walk", etc... Una animación de "Walk" combinada con mover el robot en cada frame hace ver como que el robot efectivamente camina por el terreno.
Para explorar las animaciones de un mesh bajado para OGRE se puede usar el OGRE Mesh Viewer.

Partículas

Las partíclas agregan espectacularidad al juego. Son efectos visuales en 2D rápidos de dibujar en pantalla y bonitos a la vista. Las particulas se manejan en el código usando un objeto de tipo ParticleSystem*, y se le pide crear un nuevo sistema de partículas al ParticleSystemManager.
Las partículas se pueden mostrar, ocultar (con setVisible(true o false), igual que las entidades), pero hay que mencionar que no se verán en pantalla hasta que no sean adjuntas a un Nodo. Las partículas se adjuntan a un nodo al igual que las entidades u otros nodos.
ParticleSystem* Psys;
pSys = mSceneMgr->createParticleSystem("Explosion" + String(name), "Examples/ExplosionChica");/*Lo que hicimos recien fue inicializar la partícula. El primer parámetro de createSystem es el nombre de la partícula, que como lo demás en Ogre debe ser un nombre único. El segundo parámetro es una partícula del stock de partículas de Ogre, o alguna que haya creado uno. Debe estar incluída en la carpeta de medios de Ogre */ mNode->attachObject( pSys ); //Adjuntamos la partícula para que se vea Listo! Solo con eso la partícula ya se muestra adjunta al nodo en pantalla. Las partículas se animan y hacen todo solas, dependiendo de los parámetros que les hayan puesto en su archivo.
Las animaciones de las partículas se guardan en archivos .particle en las carpetas de medios de Ogre. Allí se crea una partícula con su nombre que puede ser usada luego en el código como vimos recién. Si se hace un cambio a este archivo de configuración de la partícula para que se vea distinta, mas rápida, de otro color o con otra imágen, no es necesario recompilar el programa para que el cambio haga efecto (son como los materiales de las texturas en ese aspecto).

Gui e input

OGRE viene con un motor de GUI integrado llamado CEGUI. En la página de OGRE hay tutoriales al respecto.
Además del input básico de teclado, se pueden usar librerías como SDL para usar Joysticks u otros medios de input.

Enlaces externos

Sitio web oficial
Ogre Wiki

Fuentes

  • Joven Club de Computación y Electrónica