miércoles, 19 de septiembre de 2007

Terreno

Desde Coquimbo escribo esta actualización del Blog. Hasta ahora no he introducido nuevas mejoras al juego, por lo que este artículo representa el estado actual, que es como quedó antes de venirme a celebrar las fiestas patrias.

Cuando las entidades quedaron funcionando bien con su iluminación y cascada de texturas, decidí avocarme a construir el otro gran componente del escenario: El terreno. Sabía que no podía ser un terreno pequeño, ya que el avión recorrería grandes distancias en cada etapa. Además, a pesar de que el juego no es un simulador, por el sólo hecho de tener un avión como protagonista, merece un terreno con cerros y elevaciones.

La primera idea fue sencilla: Hacer todo con triángulos. En realidad no hay otra forma (por lo menos para mí). El problema era crear los miles de vértices que representen cada punto del terreno. Me decidí por hacer un rectángulo enorme (sólo 6 vértices), sobre el cual se superpusieran los cerros como entidades. Esta idea fue rápidamente desechada, ya que el terreno no tendría la flexibilidad para mostrar suelos ondulados, acantilados etc. Por esta razón, decidí crear todo el terreno como una sola unidad, donde las elevaciones correspondan a puntos más altos de esta única superficie. Pensé en que también debería ser autogenerado, es decir, que a partir de una matriz con datos de elevación, el programa automáticamente construyera los vértices, pusiera las normales y texturara cada subunidad de terreno. Me quedé pensando en como realizar todo esto. La solución vendría a aparecer recién e día siguiente.
Encontré en mi casa un trozo de pasto artificial, donde meses atrás vivió Pinxa, mi erizo de tierra. Por encima parecía una superficie contínua y sólida, pero al mirar por debajo se evidenciaba que no era más que una red de trabéculas plásticas, en cuya intersección se insertaba una mota de pasto plástico. La malla estaba formada de estructuras triangulares agrupadas en cuadrados, y tenía la particularidad de poder moldearse en cualquier forma. Entonces decidí usar esa misma arquitectura en mi terreno. Si pudiera asignar un valor de elevación a cada intersección trabecular (lo que corresponde a un vértice), podría crear elevación en el terreno. Ya que cada vértice era común para varias triángulos, al elevar un vértice en particular, todo el terreno que lo rodee se debería amoldar para seguir la forma del punto más alto, al igual que con el pasto plástico.
Entonces ya tenía la idea, ahora había que implementarla. Cuando comencé a pensar en código, no estaba en mi casa, por lo que no podía probar de inmediato. Escribí mi primera versión del sistema de terreno en una hoja de papel, para que al día siguiente pudiera recordarla. Cuando volví a mi casa tipeé lo que había en la hoja, llené la matriz de elevación (desde ahora el "mapa de elevación")con ceros, y lo puse a correr. El sistema generó miles de vértices en segundos, los puso en un VertexBuffer y luego mi render los dibujó. Era un rectángulo largo que representaba un terreno plano. Estaba funcionando.
El problema comenzó cuando intenté ampliar el número de subunidades de terreno. Llegué a construir tantos vértices que no hubo buffer capaz de almacenarlos. Con mi mejor tipo de vértice, cada uno ocupaba 40 bytes en el Buffer. Descubrí de manera desagradable que no podía poner más de 32767 bytes en cada buffer, y eso me limitaba a 819 vértices para todo el terreno. Tuve problemas tratando de dividir el terreno en muchos buffers, por lo que decidí descartar los buffers y almacenar toda la geometría en un array gigante, que no ha dado problema hasta ahora.
Para probar la elevación, cambié un par de datos en el mapa de elevación, simulando un desnivel en el terreno a modo de cerro. Renderizé todo en modo WireFrame para observar con detalle la malla de triángulos que formaba mi estructura. El resultado el el siguiente:



Luego probé con paneles sólidos, para ver cómo funcionaba la iluminación y mis normales autogeneradas. Decidí agregar más cerros, por lo que escribir directo en el mapa de elevación se volvió engorroso. Entonces creé una función que cargara el mapa de elevación basado en un archivo de texto. En bloc de notas escribí unos cuantos números y lo guardé como elevation.txt. Al correr el juego, automáticamente se tomaron esos datos de elevación y el mapa de elevación se autorellenó. Aparecieron todos los cerros que había definido en bloc de notas y la iluminación funcionó bien sombreando el relieve. Tomé un snapshot que se vio así:



Texturas de terreno

Cuando todo anduvo bien, fue hora de comenzar con las texturas. Agregué soporte para textura Stage 0, dibujé en paint algo que debiera parecer pasto y se lo agregué. Además agregué las casas que había hecho antes. Este es ese primer terreno texturado.



Se veia bastante bien, aunque demasiado brillante, así que decidí usar una textura de pasto real:



Posteriormente agregué el soporte de doble textura. La idea era que se pudieran mezclar dos texturas distintas para realizar transiciones de una textura a otra, agregar rugosidad a un terreno de un color ya determinado, cambiar el color de un terreno, etc. También agregué un sistema de mapeo de texturas, capaz de tomar una fracción de la textura original y usarla como textura en sí. Esto permitiría incluir muchas texturas en un mismo archivo y seleccionarlas en el mismo programa. La siguiente imagen sicodélica muestra una prueba del nuevo sistema, donde un triángulo de cada subunidad utiliza como textura a una imagen con varios colores, mientras que el otro triángulo usa como textura sólo a la porción roja de la misma imagen.



Finalmente hice que cada subunidad fuese capaz de mostrar una textura independiente. De este modo, los kilómetros de terreno ya no deberían lucir iguales. La información acerca de la versión de textura que usaría cada subunidad(en realidad referencia a una fracción distinta de un mismo archivo de imagen)está contenida en otro archivo de texto que llamé "Mapa de Texturas". De este modo, el terreno está definido en dos archivos de texto pequeños, que cuando tenga completamente definidos voy a fusionar en uno solo. También debo agregar la información sobre las entidades y su posición, lo que actualmente sólo se puede hacer desde el código.
En el siguiente snapshot se puede ver al terreno con una parte en pasto, otra con manchas blancas que corresponden a sitios de fusión con la textura stage 1; y muchas caras sonrientes. Estas últimas corresponden a la forma en que decidí que el programa manejara las subunidades para las que no hay información de textura disponible. Está lleno de estas subunidades "data not found" porque sólo designé texturas para las subunidades de la primera fila (era sólo una prueba). En realidad las caras sonrientes están formadas del blending de dos texturas: Una cara feliz (Smiley, Kirbys, o como le llamen)amarilla con lengua roja; y un fondo rojo. De esta manera se muestra como se mezclan dos texturas con facilidad. También se evidencia el sombreado en los cerros, la texturización independiente de cada subunidad, la integración con las entidades, y la generación a partir de archivos de texto. Es por esto que esta imagen, aunque no muy espectacular, muestra las capacidades máximas actuales del sistema de terreno recién creado.



La idea ahora es seguir mejorando el sistema de terreno, crear herramientas para editar con facilidad los archivos de texto (un editor de terreno o algo así)y aprender a usar un programa de edición más decente que paint para las texturas (se me está haciendo muy dificil trabajar con paint lo de las páginas de texturas). Todo eso cuando vuelva a Santiago, porque por ahora, a disfrutar mi último día de fiestas patrias. ¡Viva Chile!...

3 comentarios:

Anónimo dijo...

oli !!!

amor k wenu k puedas seguir avanzando en tu kosa....

aunke kiero ver los resultados finales ia.... aunke parece k falta muxito.... como sea...


te amo

ia eso

xaus

dikoshi dijo...

Buen blog compadre!!, ¿como haces tanta huifa en el pc? jejeje. Espero ver el resultado final, me avisas!!
Cuidate muxo!
adios!


P.D.: No estás muy grande ya para jugar con avioncitos? jejejej!!


Desuku.

Anónimo dijo...

Hola Sebita!!!

Jejeje y wenu avanzando en tu super juego!!! de verdad q no se como te haces el tiempo pa tanta cosa!!! me gustaría ser un poco como tu pa eso :P

Y aki sigo viendo tus avances en los abatares del msn y a veces en este blog... se q aun falta, pero kero q termines luego jajaja pa ver q onda el juego, teno todas las esperanzas de q es muxo mejor q el pong prueba de alguna vez, o de la invencion del cochongo pseudo copiado :P y muxo mas entrete q el king of Chile q nunca aprendi a jugar bn y me ganaste siempre!!!...

ya migoxooo!!! avance trankilo no mas y dp me muestras mas cosillas...
Como siempre suerte en todo!!! y nos estamos viendoo!!!

Te me cuidas muxoooo!!! too eso ;)

Xauu xauuu :P