Bueno después de algunas horas atrancado con esto me hago a mi mismo un resumen para intentar afianzarlo. De hecho no debería hacerlo por ser bastante sencillo. La complejidad, para mi, ha venido por mal entender un concepto y partiendo de esa falsa premisa no me entraba en la sesera el resto.

He comenzado este artículo haciendo referencia a LIBGDX que es un framework capaz de permitirnos crear una aplicación que se ejecute tanto en escritorio, como en el navegador, como en dispositivos Android (que es por lo que yo la estoy usando). Este framework contiene una “adaptación” de OPENGL ES en su interior y para desenvolverme con las funciones que hacen uso y referencia a OPENGL he tenido que ponerme a aprender algunas cosas.

En fin, OPENGL ES es …. puedes verlo aquí o aquí, una API variante de OPENGL y orientada a dispositivos integrados. A partir de ahora los conceptos que se describen son relacionados con mi experiencia con LIBGDX, que no con OPENGL que nunca lo he usado.

Entre las muchas funcionalidades de LIBGDX tenemos la de poder crear un entorno 3D y llenarlo con objetos que se representaran como si los miráramos a través de una cámara. Esta cámara tendrá su posición en el espacio, o lo que es lo mismo, sus coordenadas en el sistema de coordenadas (en adelante SC) del entorno 3D que nos crea.

El entorno 3D estará, suponemos,repleto de multitud de objetos y estos serán observados desde la posición de la cámara. Además del lugar donde se encuentra la cámara, en LIBGDX podemos definir hacia donde mira la cámara y las distancias mínima y máxima dentro de las cuales cualquier objeto sería visible y por último la relación de aspecto, es decir, el ancho y el alto de la imagen que será capturada por la cámara. Esto define lo que se denomina frustrum, que no es sino la pirámide truncada que se muestra en la figura.

Frustrum OPENGL ES

Y se puede definir con las siguientes funciones:

		PerspectiveCamera camera = new PerspectiveCamera(60, 800, 480);
		camera.position.set(0, 2, 4);
		camera.direction.set(0, -2, -4);
		camera.near = 1;
		camera.far = 1000;

 
En esas lineas de ejemplo estamos creando un objeto de tipo cámara perspectiva con una resolución de 800×480(típica de muchos dispositivos móviles), la estamos situando en las coordenadas (0,2,4) y la hacemos mirar hacia el origen de coordenadas lo que equivale al vector indicado por (0,-2,-4). Además y por último definimos la altura del frustrum indicando a que distancias cercana y lejana puede ver la cámara.

Eso en lo concerniente a la creación de la cámara. Pero lo que realmente me traía de cabeza era el tema de las matrices para incrustar otros elementos en la escena 3D. Yo por algún motivo había comprendido mal siempre que estas transformaciones gráficas partían, o mejor dicho se hacían, desde el punto de vista de la cámara. Y no es cierto. En realidad, por defecto todos los objetos que agregásemos a una escena aparecerían ocupando todos la coordenada origen (0,0,0)

La mecánica para agregar cualquier objeto PODRÍA ser la siguiente (dependiendo de las necesidades de diseño del espacio 3D concreto podrían usarse en otros orden o bien usarse unas o no otras). En fin, para describir el proceso supongamos que todo objeto 3D llega a la escena a través de un portal espaciotemporal.

Lo primero que hemos de hacer es ESTABLECER la matriz gráfica, o lo que es lo mismo asegurarnos que nuestro portal está en el origen de coordenadas.
A continuación GIRAREMOS nuestro portal los grados que sean necesarios para que el objeto aparezca con las inclinaciones adecuadas.
Después MOVEREMOS el portal a las coordenadas donde queremos que el objeto 3D aparezca.
Y, por último, ELIMINAREMOS la matriz gráfica, es decir, eliminaremos el portal.

Esto traducido a lineas de código es:

		gl.glPushMatrix();		//SITUAMOS EL PORTAL
		gl.glRotatef(30, 0, 1, 0);	//GIRAMOS EL PORTAL 30º EJE Y
		gl.glTranslatef( 1, 3, -2);	//MOVEMOS EL PORTAL A LAS COORDENADAS

		//OPERACIONES DE RENDERIZADO  Y TEXTURIZADO DEL OBJETO

		gl.glPopMatrix();		//ELIMINAMOS EL PORTAL

 
Esas operaciones se repetirían para cada objeto 3D y en última instancia algunos otros métodos asociados a la cámara serían los encargados de mostrar el resultado, pero eso da para algún futuro post.

Mientras lo he redactado me he hecho cargo de que puede parecer un autentico pegote para quien ya lo conoce, pero después de haberlo malentendido durante un buen tiempo no quería dejar pasar la oportunidad de explicarlo, principalmente para mi mismo, y que así pueda ser de utilidad en el futuro.

Un saludo