martes 21 de abril de 2009

Introducción a Motores 3D

Como lo prometí en un post hace mucho tiempo, quisiera explicar un poco acerca de lo que he aprendido de los motores 3D y la implementación de estos en OpenGL.

Un motor 3D es un programa que nos permite movernos a través de un mundo 3D visualizando objetos 3D en una pantalla 2D, a través de una serie de algoritmos complejos que utilizan la información almacenada en estructuras de datos creadas para este fin.

Podemos realizar un programa que imprima objetos 3D en la pantalla, pero implementar un motor que nos permita movernos dentro de un mundo tridimensional puede ser una tarea realmente compleja. Intentaré, a través de una serie de posts, explicar algunos principios básicos para la implementación de un motor 3D sencillo.

La tarea de crear nuestro mundo 3D contiene dos grandes desafíos:
  • La modelación de los objetos en estructuras de datos adecuadas

  • La representación de estas estructuras en nuestra pantalla 2D

Las Estructuras de Datos

Para poder crear un mundo 2D en una computadora quizás la utilización de archivos de imagenes, animaciones o dibujado de estructuras geométricas pueda bastarnos; pero, ¿cómo representar en nuestra computadora un objeto tridimensional, el cual tiene infinidad de puntos de vista, acercamientos, movimientos, etc? Almacenar cada pixel del objeto no sería práctico ni nos daría una representación muy real a la hora de mover el objeto a través del mundo virtual.

La mejor forma de modelar los objetos es a través de polígonos. Gran parte de los motores 3D utilizados en los juegos y aplicaciones modernas utilizan polígonos para modelar casi cualquier objeto en su mundo 3D. Y quizás el polígono más utilizado es el triángulo, a partir de triángulos podemos representar cualquier polígono, incluso círculos y esferas.

 



Para poder modelar cada uno de los triángulos que forman un objeto, solamente necesitamos almacenar las coordenadas de cada uno de sus tres vértices. Los vértices son los puntos principales sobre los que se basarán todos los cálculos de nuestro motor. Un vértice representa un punto en el espacio 3D y para modelarlo necesitamos almacenar su coordenada x, y, z. En C++, utilizaríamos una clase similar a esta:


class Vertex3D {

public:
Vertex3D();
Vertex3D(float, float, float);
float x, y, z;
};


Cada objeto de nuestro mundo 3D estará formado por polígonos (triángulos) que a su vez estarán formados por vértices. Hay diferentes formas de almacenar esta información en estructuras de datos: podríamos crear una clase Polygon3D que contenga 3 Objetos Vertex3D y una clase Object3D que contenga una lista de Polygon3D; pero quizás un método más adecuado sea crear una clase Object3D que contenga una lista de todos los vértices y una lista de todos los polígonos, donde cada uno de estos polígonos haga referencia a los vértices que lo forman; esto nos podría ahorrar la cantidad de objetos creados. Basado en esto, nuestra clase polígono sería algo así:

class Polygon3D {

public:
Polygon3D();
Polygon3D(int v1, int v2, int v3);
int vertex[3];
};


donde vertex[3] es un arreglo que contiene los índices de cada uno de los tres vértices que lo forman almacenados en la lista de vértices del objeto. Y nuestra clase Object3D sería algo así:

class Object3D {
public:
Object3D();

int numPolygons; // cantidad de triangulos
int numVertex; //cantidad de vertices
Vertex3D *vertex; // Lista de vértices
Polygon3D *polygon; // Lista de Polygon3Ds
};

Supongamos entonces que queremos modelar un cubo. Necesitaríamos 8 vértices y 12 polígonos como podemos ver en la figura:


En nuestro programa en C++ habría un segmento de código similar a este:

Object3D obj;

//Preparación de las listas de objetos
obj.numPolygons = 12;
obj.numVertex = 8;
obj.vertex = new Vertex3D[obj.numVertex];
obj.polygons = new Polygons3D[obj.numPolygons];

//Coordenadas de los vertices
obj.vertex[0].x = 0.0; obj.vertex[0].y = 0.0; obj.vertex[0].z = 0.0;
obj.vertex[1].x = 0.0; obj.vertex[1].y = 1.0; obj.vertex[1].z = 0.0;
obj.vertex[2].x = 1.0; obj.vertex[2].y = 1.0; obj.vertex[2].z = 0.0;
obj.vertex[3].x = 1.0; obj.vertex[3].y = 0.0; obj.vertex[3].z = 0.0;
obj.vertex[4].x = 0.0; obj.vertex[4].y = 0.0; obj.vertex[4].z = 1.0;
obj.vertex[5].x = 0.0; obj.vertex[5].y = 1.0; obj.vertex[5].z = 1.0;
obj.vertex[6].x = 1.0; obj.vertex[6].y = 1.0; obj.vertex[6].z = 1.0;
obj.vertex[7].x = 1.0; obj.vertex[7].y = 0.0; obj.vertex[7].z = 1.0;

//Poligonos formados
obj.polygon[0].v1 = 0; obj.polygon[0].v2 = 1; obj.polygon[0].v3 = 3;
obj.polygon[1].v1 = 1; obj.polygon[1].v2 = 2; obj.polygon[1].v3 = 3;
obj.polygon[2].v1 = 4; obj.polygon[2].v2 = 5; obj.polygon[2].v3 = 0;
obj.polygon[3].v1 = 5; obj.polygon[3].v2 = 1; obj.polygon[3].v3 = 0;
obj.polygon[4].v1 = 7; obj.polygon[4].v2 = 6; obj.polygon[4].v3 = 4;
obj.polygon[5].v1 = 6; obj.polygon[5].v2 = 5; obj.polygon[5].v3 = 4;
obj.polygon[6].v1 = 3; obj.polygon[6].v2 = 2; obj.polygon[6].v3 = 7;
obj.polygon[7].v1 = 2; obj.polygon[7].v2 = 6; obj.polygon[7].v3 = 7;
obj.polygon[8].v1 = 1;obj.polygon[8].v2 = 5; obj.polygon[8].v3 = 2;
obj.polygon[9].v1 = 5;obj.polygon[9].v2 = 6; obj.polygon[9].v3 = 2;
obj.polygon[10].v1 = 4; obj.polygon[10].v2 = 0; obj.polygon[10].v3 = 7;
obj.polygon[11].v1 = 0; obj.polygon[11].v2 = 3; obj.polygon[11].v3 = 7;

 

Es importante siempre definir los vértices de los polígonos en el mismo sentido, ya sea en el orden de las agujas del reloj o en sentido contrario; pero todos los polígonos deben de ser definidos en el mismo sentido para así poder determinar cual es la cara frontal del polígono.

Como podemos ver, estas clases nos permitirán entonces (con algunos métodos añadidos y algunos otros atributos importantes), modelar cualquier objeto a través de polígonos y vértices. Diseñar un cubo es sencillo, pero ¿cómo modelaríamos un rostro humano o una nave espacial? A través de código sería imposible; esto lo hacemos a través de herramientas de diseño gráfico como 3dMax, Maya, etc. las cuales generan archivos que después podremos importar a nuestro motor para montar esta información en nuestras estructuras de datos; pero eso lo mostraremos más adelante.

Por ahora es todo, en el post siguiente hablaré un poco sobre la representación de estos modelos en la pantalla 2D.

jueves 19 de febrero de 2009

Servidor PowerEdge no reconoce los discos

Me sucedió hace algunos días, días después de haber cambiado de oficina un servidor Dell PowerEdge 1800, que el servidor no me arrancaba. Esto me sucedió justo después de conectar una unidad de backup por medio de un cable SCSI externo.

Al encender el servidor me mostraba en los mensajes que no reconocía los discos duros. El servidor cuenta con dos discos duros en RAID 1, es decir donde uno es el espejo del otro. Después de intentar un rato, me comuniqué con el soporte de Dell (excelente servicio, por cierto) que me indicó los pasos a seguir para habilitar los discos duros. Al parecer el servidor los había sacado de línea para protegerlos por algún problema que detectó y sencillamente lo que había que hacer era entrar a la herramienta de administración del servidor para ponerlos OnLine de nuevo. Unas vez puestos OnLine los discos revisarían consistencia lo cual tardaría un rato mostrando una luz de color anaranjado y no verde como es lo habitual, pero el Sistema Operativo cargó sin problemas y no había perdida de información.

El personal de Dell me indicó que el problema se podría haber ocasionado por faltas de actualizaciones en el firmware o por la conexión de algún dispositivo no compatible, debido a que yo le indiqué que había conectado el backup. La unidad de backup estaba conectada al servidor en la oficina anterior así que no era falta de compatibilidad, pero yo insistía en que el problema debió ocasionarse por la instalación de la unidad y no por faltas de actualización.

Después de revisar bien la conexión me di cuenta que la conexión de unidad de cinta la había instalado mal (en el puerto equivocado de la unidad de cinta), lo que ocasionó problemas en el servidor. Pero al menos pude aprender un par de cositas que de otra forma no lo hubiera hecho.

lunes 20 de octubre de 2008

Detalles de Outlook y MSN Messenger al momento de formatear una PC

Durante este largo año de trabajo una de las cuestiones que he tenido que hacer bastante, aunque detesto hacerlo, es formatear y formatear computadoras. A pesar de la gran cantidad de veces que me ha tocado hacerlo, cada vez que debo presionar el botón "OK" para responder a la pregunta "¿Está seguro que desea formatear el disco y eliminar todo lo que está en él?" me detengo a pensar si no se me ha olvidado algo.

Cuando una computadora con Windows XP empieza a funcionar lento, a levantar mensajes de virus que ningun antivirus puede limpiar del todo, que el sistema operativo no arranca, o simplemente a hacer cosas raras, a veces es mejor tomar la decisión de formatearla. Definitivamente se debe intentar todo antes de decidir formatearla, ya que el formateo y reinstalación del sistema operativo puede significar muchas horas de trabajo y conseguir de nuevo todos los programas que la computadora necesita. Pero hay veces en que se han agotado todas las soluciones posibles: limpiar el registro de windows, borrar software malicioso, eliminar todos los virus, reinstalar archivos dañados de Windows, etc... y aun asi la computadora no funciona como debiera.

Cuando tomamos esa decisión, es importante sacar un respaldo de la computadora para que al momento de reinstalarle todo, el usuario no haya perdido su información y preferiblemente que todo funcione como funcionaba antes... incluyendo el messenger :) ...

Casi todos los encargados de formatear computadoras sacan respaldo de los documentos importantes, bases de datos, etc., pero con frecuencia se olvida (o se ignora) como sacar respaldo del Outlook y el MSN Messenger. Aunque esta información puede no ser relevante para algunas personas, el hecho de dejarle al usuario la computadora tal como la tenía generará una sensación de agradecimiento y satisfacción en él.

Microsoft Outlook.

Al momento de sacar respaldo de la información de outlook hay tres tipos de información que debemos considerar:
  • Libreta de direcciones, Calendario, Tareas, Bandeja de entrada, Elementos enviados y Elementos eliminados
  • Carpetas Archivadas
  • Direcciones a las que se ha enviado correos

Hacer un respaldo del buzón principal y las carpetas archivadas es una tarea muy conocida y que no implica mucho problema. Pero si solamente respaldamos la libreta de direcciones, al momento de restaurar el sistema, el usuario preguntará por gran cantidad de direcciones que ya no encuentra.

Microsoft Outlook, además de la libreta de direcciones, mantiene un caché de las direcciones a las cuales les hemos enviado un correo. Es por eso que al momento de escribir una letra en el campo "Para..." cuando estamos redactando un correo electrónico, nos aparece una lista con varias direcciones que empiezan con esa letra. Estas direcciones no son las direcciones de la Libreta de Direcciones (o Contactos) sino del caché del outlook. Estas direcciones se encuentran en la carpeta C:\Documents and Settings\<nombre de usuario>\Datos de programa\Microsoft\Outlook o C:\Documents and Settings\<nombre de usuario>\Application Data\Microsoft\Outlook para las versiones Windows en inglés. El archivo que contiene estas direcciones es el archivo con extensión .NK2. Solo necesitamos copiar este archivo y restaurarlo en la carpeta con el mismo nombre al momento de configurar nuevamente el outlook.

MSN Messenger

Generalmente al formatear una computadora perdemos todos nuestros emoticons, background, guiños, etc. que usamos en el msn messenger. Estos archivos podemos moverlos de computadora a computadora sin problema solo necesitamos iniciar sesión en la computadora destino y luego sustituir en la carpeta C:\Documents and Settings\<nombre de usuario>\Configuración local\Datos de programa\Microsoft\Messenger\<dirección de correo electrónico>\ObjectStore o C:\Documents and Settings\<nombre de usuario>\Local Settings\Application Data\Microsoft\Messenger\<dirección de correo electrónico>\ObjectStore la carpeta que deseamos, ya sea Bakcgrounds, CustomEmoticons o Winks3 provenientes de la computadora origen. Al momento de formatear una computadora solo necesitamos sacar respaldo de estas carpetas y sustituirlas después de iniciar sesión en el messenger.

De regreso...

Después de un año de ausencia, he decidido volver a escribir en el blog.

Ha sido un año muy cargado de trabajo, lo que me ha impedido avanzar en algunos proyectos personales que tenía, en algunas cosas que quería aprender y definitivamente en actualizar el blog.

Espero poder retomar el ritmo y escribir más seguido de hoy en adelante...