martes, 4 de diciembre de 2012

Más modelado.

music: MERCYFUL FATE -"Room of Golden Air"-



Por aquí dejo otra cosilla de modelado; con esto estuve liado hace unas semanas.

Hasta otra. :P

viernes, 2 de noviembre de 2012

Modelando (que también es gerundio). :P

music: ALASKA Y LOS PEGAMOIDES -"Mundo Indómito"-



Mi particular "Hello World!" dentro del mundo del modelado 3D y texture mapping.

Hasta otra. :P


martes, 9 de octubre de 2012

Refactoring, refactoring...

music: DEVO -"Beautiful World"-

...y más, y más refactoring.

Y vuelta a empezar.

Pero al fín el proyecto tiene una estructura de directorios cohesiva (y coherente). Aparte, ha quedado actualizado a DirectX SDK (june 2010).

Y ahora tocará... limpieza y más limpieza de código. En fín...

Hasta otra. :P

martes, 28 de agosto de 2012

Bye, bye, warning C4921...!!!. :D

music: MASTODON -"Seabeast"-

La perseverancia a veces da sus frutos, ¡pardiez...!.

De nuevo, otro tema ha sido arreglado. No era un problema grave pero era algo que me estaba tocando la moral desde el principio (y de hecho, todavía me cuesta hablar en términos de pasado, como algo que ha desaparecido, que ya se ha solucionado). :P

Se trataba de una serie de warnings que aparecían durante la compilación del juego, cuyo código era C4291. Se limitaban a "aparecer", a estar ahí, dando un mensaje que hasta ahora me resultaba ilegible, cada vez que reservabas dinámicamente memoria para crear un objeto teniendo en funcionamiento el sistema de control de memory leaks. Y varias veces a lo largo de todo este tiempo me había puesto a intentar ver por qué se producían y qué hacer para que no salieran... sin éxito. Hasta ahora. : )

Y no, la solución no ha venido añadiendo al código  #pragma warning ( disable : 4291 )  :P

El asunto es: cuando activamos el sistema de control de memory leaks en el engine se realiza una sobrecarga de los operadores new y new[ ]. En concreto la sobrecarga 'Placement Form' de éstos, adoptando una cabecera así:

void* operator new      ( uint uSize, char* pszFile, uint uLine );
void* operator new[]    ( uint uSize, char* pszFile, uint uLine );

Pues bien, dado que estos son los operadores new y new[ ] que se sobrecargan, hay que hacer también las sobrecargas de delete y delete[ ] con esta misma estructura, es decir, así:

void  operator delete   ( void* p, char* pszFile, uint uLine );
void  operator delete[] ( void* p, char* pszFile, uint uLine );

La razón argumentada es que, si se crea dinámicamente un objeto y en el constructor de éste salta una excepción, se pueda liberar la memoria que había sido reservada para el objeto empleando dichas sobrecargas de delete y delete[]. Pero las únicas sobrecargas que había definidas hasta ahora eran:

void  operator delete   ( void* p );
void  operator delete[] ( void* p );

Pues... por eso daba los cansinos warnings. :P Al añadirle las otras sobrecargas de delete y delete[ ] a éstas últimas al fín han desaparecido, ¡joas, joas...!. :D

Mas información aquí.

En mi caso lo anterior nunca se va a producir pues, dada la arquitectura del engine, en los constructores de las clases no se hace nada "raro" que pueda provocar el lanzamiento de una excepción, no se hace nada más allá que inicializar a NULL, false ó 0 algunos atributos de la clase... dejando la "auténtica" inicialización del objeto en el método Init, llamado inmediatamente tras la creación del objeto, que todas las clases poseen. Por ello las nuevas sobrecargas quedan como una mera formalidad, pues no son empleadas dentro del engine (no se necesitan, y se siguen empleando las que ya había). Pero como digo siempre: El problema es no saber, y ahora que sé por qué se producía el tema, no me apetece quitarlas para no olvidarlo. XD

Hasta otra. :P

miércoles, 6 de junio de 2012

Reality, a New Beginning

music: FIGHT -"Reality, a New Beginning"-


This time, when I'm leaving... who cares where I'll go?.
I'll walk with the sunset. Out there... no one knows.

Reality, a New Beginning...

In my imagination I'm searching for my dreams.
Finding something better. More than what I've been.

Reality, a New Beginning...

New day, new tomorrow. I'm not living in the past.
Changing the illusion I'm set free... free at last.

Reality, a New Beginning...

* * * * * *

Si Madrid ya no nos quiere... enamorémonos de nuevo.


miércoles, 16 de mayo de 2012

Terrenos y Mapas de Alturas

music: L7 -"Pretend We're Dead"-

( NOTA: es probable que cambie las partes en las que digo píxel por téxel, dado que, aunque lo que voy a llamar Mapa de Alturas no es una textura propiamente dicha -no se mapea en ningún modelo 3D-, el concepto de píxel parece estar semánticamente más asociado con el monitor, mientras que el de téxel lo está más con una unidad atómica, indivisible, de una imagen. Aún no estoy seguro, de momento lo dejo como TO-DO ).

En los últimos días he estado desempolvando uno de los que fueron mis programas favoritos del Máster. Con él se genera la representación visual de un terreno a partir de un Mapa de Alturas, esto es, una imagen de escala de grises (o como es mi caso, una imagen RGB a la que hemos "desatudado" el color) cuyos valores de gris (color) equivalen a una determinada "altura" en un mundo 3D; esto es, a un determinado valor positivo a la coordenada Y de cada uno de los vértices que conforman el terreno.

Así, como valores extremos del rango:

-Un pixel en el mapa de alturas que tenga un color Negro (R:0, G:0, B:0) otorgará un 0.0 como valor a la coordenada Y del vértice correspondiente a ese píxel en el terreno, vamos, en el mundo 3D.

-Y un pixel en el mapa de alturas que tenga un color Blanco (R:255, G:255, B:255) otorgará un valor máximo como valor a la coordenada Y del vértice correspondiente.

Para preparar el Mapa de Alturas se parte de una imagen a la que, mediante Photoshop , hemos quitado el color, retocado a nuestro gusto y por último escalado a un tamaño de 128x128 píxeles. La guardaremos empleando el formato Photoshop RAW (*.RAW), que no debe confundirse con imágenes RAW de cámara digital (so pena de perder un montón de días haciéndote el lío padre como me pasó a mí). :P A todo esto, debo comprobar si el nuevo GIMP 2.8 también tiene soporte para abrir imágenes Photoshop RAW.

No necesitaremos que el fichero posea una cabecera que contenga el ancho y alto de la imagen en píxeles, pero justo por ello sí tendremos que ser nosotros los que tengamos que indicar al "Objeto Terreno" el tamaño del Mapa de Alturas que le pasamos  (que como ya hemos dicho, será 128 píxeles de ancho y de largo).

A partir del Mapa de Alturas tendremos en el mundo 3D una malla poligonal cuadrada de 128x128 = 16384 vértices, dividida en (128 - 1) * (128 - 1) = 16129 sectores cuadrados contiguos, como una rejilla. Pero dado que la unidad atómica que nos interesa para renderizar es el triángulo -y no el cuadrado-, dividimos cada sector en dos triángulos rectángulos que comparten la hipotenusa. El número total de triángulos será el doble que el de sectores, esto es, 32258. : )

Por último, se crea un Vertex Buffer y un Index Buffer, y las coordenadas X,Y y Z son calculadas para cada vértice e introducidas, con la ayuda del Index Buffer, en el Vertex Buffer.

Aquí es donde entra en juego al Mapa de Alturas. Como anteriormente se ha mencionado la coordenada Y del actual vértice (del aquel que hay que generar actualmente las coordenadas, vamos) se toma consultando el valor de color del píxel correspondiente en el Mapa de Alturas; en concreto, se consultará la componente de color G de dicho píxel. Las coordenadas X y Z se generan a partir de un valor de espaciado entre sectores (un valor fijo, actualmente es 16) y de unos Offset en X y en Z: el offset en X es la mitad del ancho del Mapa de Alturas, y el Z la mitad del alto (para el caso, ambos valdrán 64).

Así, si pensamos en una rejilla o matriz 2D a cuyas filas accediéramos mediantes en índice i y a cuyas columnas accediéramos mediante el índice j, las coordenadas X,Y,Z para cada vértice 3D [i][j] se calcularían así:

Vertice3DActual[i][j].X = (i * EspaciadoEntreSectores) - (Offset_X * EspaciadoEntreSectores)
Vertice3DActual[i][j].Y = MapaAlturas[i][j].Componente_G
Vertice3DActual[i][j].Z = (j * EspaciadoEntreSectores) - (Offset_Z * EspaciadoEntreSectores)

Tras haber calculado las coordenadas de todos lo vértices se calculan las normales para los tres vértices de cada triángulo, los índices para el Index Buffer, se sitúa una cámara libre dotada de un movimiento básico de 6 grados de libertad y... estos son los resultados.




La flecha roja indicaría a grandes rasgos la posición y orientación de la cámara. Efectivamente, la última escena es un poquito "marciana". ; )

Hasta otra. :P

martes, 15 de mayo de 2012

Retromadrid 2012

music: ANA CURRA -"Envuelta en ron"-/-"Tengo un pasajero"-

La mala noticia en 2011 fue que no habría Retromadrid ese año. La buena, que la edición de 2012 se realizaría en el Centro Matadero de Madrid... como así ha sido.

El lugar adjudicado para el evento es verdaderamente espacioso y cuenta con dos salas separadas, la principal y la de conferencias. Es probablemente el lugar más amplio en el que Retromadrid se haya realizado.

Hablaré del domingo, día 6, que fue el día que yo asistí. Las actividades principales de dicho día, aparte de la sesión de firmas por parte de nuestro incombustible Azpiri, era la ponencia Detrás de los muros de la Abadía del Crimen (yo me referiré a ella como 2.0, para diferenciarla de la de Gamefest 2011) y la mesa redonda Ocho Quilates: una historia de la Edad de Oro del software español. Título homónimo del libro que debe ya estar a punto de salir. :P

Al comienzo de Detrás de los muros de la Abadía del Crimen 2.0 se contactó por videoconferencia con J. Delcán, quien había accedido a participar pese a que en California ya debía ser bastante tarde. :P Desgraciadamente, el gran reverb que se producía mientras hablaba (no sé si era por la sala o por los altavoces) impidió que nos enteráramos de gran parte de lo que decía. Probé a situarme en varios puntos distintos de la sala, a ver si encontraba algún lugar donde le escuchase mejor... pero no sirvió. :(

¿Y qué tal fue esta versión 2.0, respecto de la anterior en Gamefest 2011?. Aunque “a grosso modo” las explicaciones en esta ocasión resultaron más atropelladas (quizás empezaron a ver que ir mal de tiempo, y aceleraron en el último tramo) respecto a la edición anterior, y por ello el resultado final de la anterior queda como algo más compacto y mejor atado, en esta segunda edición añadieron un montón de elementos complementarios muy interesantes, que hace que su visionado (cuando se suba a la red) merezca definitivamente la pena. Destáquese:

-Una demostración en tiempo real acerca de cómo se generan las letras del pergamino del principio, el que escribe un ya anciano Adso, y que parecen estar escribiéndose a mano.

-Una demostración visual sobre la IA de los NPCs (Adso, los monjes) y cómo buscan el camino a través de la Abadía para llegar al lugar donde tienen que ir en un determinado momento. Para el ejemplo se empleó a Severino y al Abad.

-También se incluyó una representación animada de Fray Guillermo caminando, realizada superponiendo los diseños en papel de éste en las diversas poses de caminar, y algunos diseños personalizados para los monjes que al final tuvieron que descartarse por limitaciones de RAM (el tronco y las extremidades de los monjes parten todos, al final, del mismo modelo... cambiando únicamente las cabezas).

-Se mostró un bloque de código/script, programado en ensamblador, para controlar parte de la lógica general del juego. No recuerdo ahora qué condición/es del juego controlaba.

Aparte, agradezco a A. Giner la inclusión de Ant Attack en la explicación preliminar de la ponencia. No recuerdo si al final le dí las gracias cuando volví a hablar con él tras acabar esta; si se me pasó, sorry, A. y... ¡¡¡MUCHAS GRACIAS!!!. : )

Y tras recibir Azpiri un MOT-premio por su trayectoria profesional comenzó la mesa redonda Ocho Quilates, en la que los invitados nos obsequiaron con otro buen montón de historias, anécdotas y curiosidades para añadir a nuestra base de conocimiento sobre aquella época que muchos sólo vivimos como jugadores incansables y programadores aficionados. :P


Por último, añadir que este movimiento, lejos de quedarse apolillado y permanecer estático y encasillado, va evolucionando y se renueva, introduciéndose nuevos elementos. Prueba de ello es haber visto en las vitrinas de la exposición sobre videoconsolas una Xbox (es de esperar que, dentro de 5 o 10 años, veamos por ejemplo una Xbox360). O cómo, durante la propia Ocho Quilates, asomaron de forma natural temas como los smartphones o las plataformas de descarga digital.

Hasta otra. :P