Source: http://varrojo.algorithmia.net/page/2/
Timestamp: 2017-07-23 14:30:44+00:00

Document:
Varrojo@Linux | Just another WordPress site | Page 2
Posted on November 28, 2010 by admin	Hoy estuve configurando una placa de video Intel GMA500, encontrada en Netbooks como el Dell Mini 10, para que funcione correctamente con Ubuntu Maverick (10.10).
Ubuntu Maverick (10.10) tiene una apariencia visual muy atractiva, si logramos configurar la resolución correcta.
La GMA500 es una placa de video que por defecto causa problemas en Linux, en particular en Ubuntu Maverick, y para configurarla resulta necesario instalar un driver de video apropiado.
Revisando la Wiki de Hardware de Ubuntu, noté que se recomienda utilizar el driver Poulsbo, sin embargo, desde hace varios releases de Ubuntu, este driver rompe la reproducción de video. Dado que esta computadora estaba siendo configurada para un usuario final, esto no era una opción.
Buscando alternativas, dentro de la Wiki se encuentra una página con drivers alternativos a Poulsbo. Finalmente me decidí por utilizar el driver fbdev, el cual es sencillo de instalar.
Dejo los pasos que me funcionaron a continuación, tomados de la Wiki de Ubuntu.
Para instalar el driver, abrimos una terminal y utilizamos apt-get:
Una vez instalado, necesitamos indicar al Kernel que debe cargarse el módulo en forma automática al bootear. Para eso editamos el archivo /etc/modules y agregamos las siguientes líneas:
Luego, debemos crear el archivo /etc/X11/xorg.conf con el siguiente contenido:
Una vez configurado, debemos especificar a nivel de GRUB la resolución con la que deseamos utilizar la pantalla. En el caso de un Dell Mini 10, la resolución ideal es 1024×576 (con 32 bpp).
Para esto debemos crear el archivo /etc/grub.d/01_915resolution y agregar las siguientes líneas:
echo 915resolution 58 1024 576 32
Parece raro, pero los “echo” deben aparecer. Una vez creado, hacemos de este archivo ejecutable:
Ahora debemos editar el archivo /etc/default/grub y asignar la resolución deseada a las variables GRUB_GFXMODE y GRUB_GFXPAYLOAD_LINUX:
GRUB_GFXPAYLOAD_LINUX=1024x576x32
Finalmente, actualizamos GRUB:
Si todo funcionó correctamente, al reiniciar la computadora, deberíamos tener la resolución especificada.
Si al iniciar sesión en Ubuntu se nos despliega un mensaje de error indicando que no se puede establecer la resolución a la requerida, pero de todos modos la resolución es correcta, debemos editar el archivo $HOME/.config/monitors.xml y ajustar los valores del ancho, alto y (probablemente) el refresh rate.
Posted on November 21, 2010 by admin	Este fin de semana estuve trabajando de a ratitos en el soporte para Lightmaps para el renderer de mapas de Quake 2. Afortunadamente implementar los lightmaps no fue tan costoso como el soporte para el mapeo de texturas.
Cuarto escondido en base1.bsp, renderizado con Lightmaps. Quake 2 permite acelerar mucho el rendering de polígonos precalculando la iluminación que afecta a cada uno en la etapa de compilación del Árbol BSP. Estos cálculos son almacenados en la forma de una textura de iluminación (Lightmap) que luego puede multiplicarse por la textura del polígono para obtener un efecto de tener sombreado y sombras en la escena, sin deber realizar el cálculo en tiempo real.
Quienes jugaron Quake 2 recordarán la psicodelia típica de los mapas, lo cual distingue mucho la apariencia visual del Quake 2 de la del Quake original. Esto se debe a que los Lightmaps de Quake 2 son imágenes RGB de 24 bits por pixel, permitiendo mapear no solo sombras y sombreado, sino también colores sobre los polígonos. Esto se utiliza mucho en los cuartos de exteriores, donde se quiere expresar la hostilidad de la atmósfera del planeta Strogg, y para implementar luces cromáticas.
Cuarto exterior en base1.bsp renderizado con sus Lightmaps.
A nivel de implementación el Lightmap es simplemente otra textura que debe mapearse sobre los polígonos junto con la proveniente del archivo WAL. Para combinar ambas texturas utilicé multitexturing y escribí un Shader que multiplica los texel provenientes de cada una de las dos imágenes en tiempo de ejecución.
Prefusionar el Lightmap con la textura difusa hubiese sido más rápido, sin embargo, esto no fue una opción dado que cada polígono tiene su propio Lightmap asociado, a diferencia de las texturas difusas, las cuales son compartidas entre varios polígonos.
La dificultad más grande que enfrenté para esta tarea fue calcular las coordenadas de textura del polígono en el Lightmap (las cuales son distintas de las coordenadas utilizadas para la textura difusa). Tras bastante ensayo y error, terminé encontrando la fórmula correcta en los foros de GameDev.net, aquí. Mil gracias al autor del post, realmente esta fórmula no se encuentra por ningún lado y buscarla en el código fuente del Quake 2 es una tarea muy tediosa.
Finalmente, a modo de comentario, los Lightmaps agregan muchísimo realismo al renderer, sin embargo, tienen un costo asociado. En particular, al existir un Lightmap por polígono, para un mapa de aproximadamente 9.500 polígonos (como base1.bsp), esto implica que tendremos 9.500 texturas más, aumentando un poco el consumo de memoria de video, pero -más importante- obligándonos a realizar más llamadas a glBindTexture en cada cuadro, realmente perjudicando el framerate. Existen varias estrategias para intentar resolver este problema, alguna de las cuales intentaré tras terminar de mejorar el aspecto visual de los mapas.
A continuación dejo algunas capturas realizadas con el renderer. Nótese el realismo agregado a la escena, sobre todo comparando con el post anterior, en el cual solo mapeábamos texturas. Para generar estas imágenes, modifiqué la proyección perspectiva a una más “suave”. Creo que la matriz actual es más parecida a la utilizada por el Quake 2.
Finalmente, notarás que el cielo sigue roto, afortunadamente tengo alguna idea para desarrollar un Shader especial para el cielo que permita renderizarlo como en el Motor original de Quake 2.
Cuarto Final de base1.bsp, con el ascensor a la Installation (base2).
Cuarto de inicio en base1.bsp. Notar que el cielo no se renderiza bien debido a que no dispone (aún) de su propio shader.
Posted on November 16, 2010 by admin	Este artículo es una continuación de “Rendering de Mapas de Quake 2“. Tras bastante más trabajo del que estimé originalmente, finalmente logré agregar soporte para realizar Mapeo de Texturas sobre los mapas BSP de Quake 2. En este artículo voy a intentar explicar los detalles sobre como funcionan los archivos de textura utilizados por Quake 2, de forma de poder dibujar el mapa textureado por Hardware, utilizando OpenGL.
Primer mapa del Juego, renderizado desde la posición de inicio del jugador con mapeo de texturas.
Quake 2 almacena sus texturas en un formato propio denominado WAL. Para realizar el mapeo de texturas fue necesario implementar soporte para este tipo de archivos de imagen. Los archivos WAL se almacenan dentro del archivo PAK del juego y son básicamente índices a una paleta de colores que también se encuentra dentro del PAK. Para poder recomponer la textura como una matriz RGB, es necesario disponer tanto de cada WAL individual como de la paleta y por lo tanto fue necesario desarrollar una forma de poder cargar estos archivos directamente desde el PAK.
La ventaja de soportar los archivos PAK originales del juego es que ahora puedo cargar los recursos del juego directamente desde ahí (incluso los mapas BSP), sin necesidad de previamente extraerlos.
Comenzemos estudiando la paleta de colores. La paleta se encuentra dentro del PAK bajo el nombre “pics/colormap.pcx”. Para poder acceder a su contenido es necesario cargarla en memoria desde el PAK como un BLOB. Este BLOB es una imagen codificada en PCX, y es necesario descomprimirla para poder utilizarla como una matriz de colores.
Luego, cada WAL correspondiente a un polígono es referenciado mediante su nombre y ruta dentro del PAK. Los WAL consisten principalmente en un header que determina, entre otras cosas, las dimensiones de la imagen y el offset donde comienzan los datos. Los datos a leer son exactamente w*h bytes a partir de offset[0]. Estos datos son una matriz de índices a la paleta de colores. Afortunadamente, estos datos no se encuentran codificados de ninguna forma y pueden utilizarse directamente para indexar la paleta de colores.
A modo de comentario, cada índice leído es exactamente un byte de tamaño, por lo cual los WAL en teoría no pueden referenciar más de 256 colores distintos en la paleta. Consecuentemente, uno esperaría que la paleta sea exactamente de 256*3 bytes, sin embargo, esto no es así. Quizás otros aspectos del motor utilizan la misma paleta y por eso existen colores que en principio no podrán ser referenciados.
Una vez que tenemos el WAL y la paleta, la textura se crea fusionándolos en una matriz de colores RGB. Esto se puede hacer de dos formas: se puede suministrar la paleta a OpenGL y luego crear una textura compuesta por índices, o bien, se puede fusionar la paleta con el WAL manualmente por Software y suministrar texturas 2D ya preparadas a OpenGL.
El primer enfoque tiene la ventaja de que se ahorra mucha memoria de video, ya que por cada textura, necesitamos almacenar solamente 1/3 de los datos que necesitaríamos para almacenar colores RGB (más la paleta una única vez). Por otro lado, este enfoque es más difícil de configurar a nivel de OpenGL (yo no logré hacerlo andar), requiere que la implementación de OpenGL soporte la extensión ARB_imaging y es más lento en tiempo de ejecución, ya que OpenGL deberá fusionar la paleta con los índices por cada cuadro. A su vez, OpenGL no soporta paletas del tamaño de la del Quake 2 e, incluso si lo hiciera, deberíamos convertir todas nuestras matrices de índices a dimensiones potencias de 2.
El segundo enfoque resuelve todos estos problemas al costo de consumir más memoria de video. Personalmente elegí este segundo enfoque, al costo de saber que probablemente mi renderer tenga problemas de performance en placas de video con poca RAM (64 MB?).
Si w,h son las dimensiones del archivo WAL, “textura” es una matriz de w*h*3 bytes, “indx” el i-ésimo índice del archivo WAL y “paleta” la paleta de colores, la forma de fusionar manualmente la paleta con los índices en un array es mediante la siguiente operación:
textura[i*3+0] = paleta[indx*3+0];
textura[i*3+1] = paleta[indx*3+1];
textura[i*3+2] = paleta[indx*3+2];
Donde i es un contador en el intervalo [0, w*h), y teniendo cuidado de no leer fuera del espacio de memoria de la paleta. Es válido referenciar colores fuera de la paleta, si bien los WAL de Quake 2 no parecen hacerlo. Si esto llegase a pasar, se deberá forzar el valor a negro (0x0).
La paleta se asume es un array unidimensional de la forma R,G,B, R,G,B, … Es por esto que la forma en que se indexa la paleta es tal que el índice 0 corresponde a los primeros 3 bytes (0,1,2), el índice 1 corresponde a los siguientes 3 (3,4,5) y así sucesivamente.
Una vez creada nuestra textura RGB, la cargamos a OpenGL y ésta queda pronta para ser utilizada.
El último detalle a tener en cuenta es la diferencia entre los sistema de coordenadas de textura de Quake 2 y de OpenGL. Quake 2 utiliza un sistema de coordenadas en píxels, mientras que OpenGL utiliza un sistema normalizado. Para solucionar esta diferencia es necesario (tras calcular las coordenadas u,v de textura), dividir u y v entre el ancho y largo de la textura respectivamente. Esto no necesariamente producirá coordenadas en el intervalo [0,1], lo cual es esperable, ya que muchas de las texturas en Quake 2 deben dibujarse con Tiling.
Sin más detalles, les dejo a continuación un par de screenshots nuevos, esta vez con la iluminación deshabilitada pero con texturas mapeadas con filtrado bilineal.
Cuarto de Ambiente Exterior en Base 1, con mapeo de texturas. Notar los Triggers puestos en el cuarto para disparar eventos en el Juego y como el cielo se ve "raro" al dibujarlo como cualquier otro polígono.
Cuarto escondido en Base 1.
Posted on November 13, 2010 by admin	Desde hace algún tiempo he estado considerando la posibilidad de aprender Lua, un lenguaje de programación desarrollado en Brasil muy popular para implementar motores de scripting en juegos.
Casualmente me encontré hace algunos días esta CheatSheet que llegaba a la portada del Programming Reddit.
Lua CheatSheet - Lua es un lenguaje muy parecido a Python!
Me pareció un excelente recurso para rápidamente hacerse con una buena impresión del lenguaje. ¡Muchas gracias al autor en CoffeeGhost!
Posted on November 10, 2010 by admin	Estos últimos días tuve que quedarme en cama, y aproveché el tiempo para investigar y experimentar (cuando podía leer) sobre el formato interno de los mapas de Quake 2.
Primer mapa del Juego, renderizado desde la posición de inicio del jugador.
Internamente, los mapas de Quake 2 son un Árbol BSP con información de “visibilidad”. Esto se debe a que el motor del Quake 2 era un híbrido entre un motor de Árboles BSP y Portal Engine, utilizando el árbol para determinar rápidamente la hoja en la cual se encuentra la cámara y luego la información de visibilidad para descartar grandes porciones de los mapas a la hora de dibujar.
El formato es relativamente simple de leer ya que básicamente se trata de un conjunto de blobs con un directorio. Esto hace que sea extremadamente sencillo de levantarlo desde C o C++.
La mayor dificultad con la que me encontré consistió en dar un formato a estos datos que sea razonable para enviarlos a OpenGL en forma eficiente (recordemos que es un formato del ’97). Particularmente, a mi gusto, existe demasiada “distancia” entre las hojas del Árbol BSP que contienen geometría y los detalles de la misma, debiendo atravesar varias tablas para llegar desde una hoja que se sabe visible hasta las coordenadas de los vértices que componen todos sus polígonos.
Finalmente se me ocurrió una forma de transformar todos los polígonos para evitar el tener que estar saltando entre 6 tablas cada cuadro a dibujar : )
El renderer dispone de un sistema de iluminación muy básico, con luces direccionales y brillo especular.
Los próximos pasos que me gustaría realizar serían implementar el mapeo de texturas (idealmente leyendo los archivos .wal originales del juego desde el paquete .pak) y el descartado de geometría mediante el cálculo del PVS.
Les dejo algunos screenshots.
Cuarto de "Exteriores" en base1.bsp
Cuarto de inicio del segundo mapa (base2.bsp).
Posted on October 28, 2010 by admin	Hace 32 días que no rebooteo mi Laptop. Creo que desde que actualicé a Snow Leopard (y dejé de desarrollar CUDA en él) nunca más tuve que reiniciarlo.
Posted on October 25, 2010 by admin	Encontré el libro completo “C: How To Program” de Deitel & Deitel en Google Books.
Por suerte Google Books provee una forma fácil de embeberlo en un iframe. Lo dejo a continuación.
Posted on October 18, 2010 by admin	El pasado 14 de Octubre de 2010 falleció Benoit Mandelbrot, un famoso matemático Franco-Americano nacido en Polonia.
Posted on October 14, 2010 by admin	Hace algún tiempo, conversaba con un colega de mi Universidad sobre la forma en que se enseña a programar a los estudiantes.
En mi Universidad, el lenguaje de programación utilizado para enseñar a programar es Java. Como parte de nuestra conversación, le comentaba a mi colega las desventajas que personalmente percibía en usar dicho lenguaje con el propósito de enseñar conceptos básicos de programación y por qué personalmente pienso que no logra compararse contra enseñar un lenguaje como C.
Este artículo intenta recapitular los puntos más interesantes de dicha conversación. Si bien me enfoco en Java, lo dicho aquí perfectamente aplica a C# también.
Supongamos que eres un profesor de Primero, enseñando los fundamentos de la programación, y yo soy uno de tus alumnos.
¿Cómo dictarías este curso? Pues, si te pareces en algo a mi, probablemente en la primer clase de Laboratorio escribirías un clásico programa “Hola Mundo” en el pizarrón y le pedirías a tus alumnos que lo prueben.
Ahora, si estás usando Java, lo primero que deberías hacer es pedirnos a los estudiantes que iniciemos nuestros “IDEs”, creemos una nueva “clase” y copiemos el programa del pizarrón en un nuevo “método”…
Yo, como tu estudiante, quien jamás ví nada de programación en el Liceo, probablemente no sepa de qué me estás hablando tan pronto mencionaste la palabra “IDE”. Tu, como profesor del curso, pacientemente me explicarías que los “IDEs” se utilizan para escribir y ejecutar programas en una computadora y que lo más probable sea que tenga que usar un “IDE” cada vez que vaya a hacer un programa.
Quizás, como estudiante, acepte tu explicación o, quizás, pregunte por qué es que jamás había escuchado de un “IDE” cuando utilizo programas de todo tipo en mi computadora desde siempre. Si tienes poca suerte y te realizo la segunda pregunta, ¡BAM! instantáneamente tendrás que explicarme la diferencia entre el “desarrollar un programa” y “ponerlo en producción”, o bien, pedirme que “haga un acto de fé en que las cosas son así” y que me limite a pensar en el ejemplo en el pizarrón.
Ok… en cualquiera de los dos casos no entiendo qué es un “IDE”, ni por qué lo necesito, ni por qué estamos usando éste y no otro, pero bueno, sigamos adelante. Este es un curso de programación, después de todo, no de “IDEs”.
Bien, tu dijiste que cree una nueva “clase” y copie el programa del pizarrón en un “método”. ¿Podrías explicarme bien qué es una “clase” y qué es un “método”?
Oops… Como profesor ahora sí que estás en problemas. Claramente estos son conceptos de Programación Orientada a Objetos y, ciertamente, no quieres comenzar a estudiar este tipo de cosas antes de que tus alumnos ni siquiera hayan escrito su primer programa “Hola Mundo”. Lo único que puedes hacer en este caso es, nuevamente, pedirle a tus estudiantes que confíen en tí ya que “las cosas son así en Java”.
Bien, como tu estudiante, nuevamente acepto ciegamente lo que me dices (sin tener idea de qué es nada de lo que estoy haciendo ni por qué) y finalmente mi programa se parece a lo siguiente:
Presiono el botón de “Play” en mi “IDE” y funciona. Todo parece estar en orden. Todo excepto un detalle: ¿cuántos conceptos en este pequeño fragmento de código piensas que hay, de los cuales tus estudiantes no tenemos ni idea de qué son o por qué están ahí? Pues, probablemente de todo esto no solo comprendamos muy poquito, sino que además ya estemos dudando de si seremos capaces de escribir siquiera un programa por nuestra cuenta, sin ayuda del Profesor.
La peor parte es que, de todos los conceptos que hay dentro de este fragmento de código, ¿cuántos son realmente razonables de ser explicados en un curso de Programación 1? ¿Solo println, quizás?
¿Por qué? Pues porque para poder explicar qué es una “clase”, qué es un “método” y qué son: “public”, “static”, “String[]”, “System” y “out”, tengas que comenzar a enseñar conceptos de POO desde el primer día de clase y realmente no quieres hacer eso, por dos motivos: 1) terminarás confundiendo a todos tus estudiantes y 2) la mayoría de todos esos conceptos no resultan útiles para para este curso en absoluto!
Entonces… si enseñar de esta manera parece tan complicado, ¿por qué estas usando Java para enseñar a programar? Si me preguntas a mi, pienso que no deberías. Personalmente pienso que C sería un candidato mucho mejor.
Compara el programa Java anterior con el equivalente en C:
¿Cuál piensas que es más fácil de explicar a alumnos de Primero? A lo sumo probablemente termines explicando qué significa “#include”, a lo cual puedes simplemente responder que es un archivo donde printf está definido. Con eso basta. Nada de complicaciones ni “actos de fé”. Nada de “public static void main(String[] args)”. Tan solo un simple printf.
¿Qué sucede con todo el lío del “IDE”? Pues, resulta que un simple editor de texto con resaltado de sintaxis y un compilador de C son todo lo que realmente necesitas. Compilar código C es extremadamente sencillo, si el sistema se encuentra correctamente configurado. Un comando como el siguiente es suficiente para producir un ejecutable:
Es así de sencillo y lo mejor de todo es que obtienes un ejecutable. Un simple archivo .exe sobre Windows. Eso es lo que tus estudiantes están esperando. Eso es lo que un programa es para ellos: un archivo .exe. En Java, tu compilador hubiese generado un archivo “.class” y tendrías que explicar a tus alumnos cómo invocar la Máquina Virtual de Java, explicar qué es un Runtime y por qué es necesario para que tu código (que ya está compilado, ¿no?) ejecute.
Una ventaja final: pidiendo a tus estudiantes que compilen su código a mano (en vez de usar el botón “Play”), indirectamente les estás pidiendo que aprendan a utilizar la aplicación Terminal (créeme, la mayoría de los estudiantes no saben qué es esto o cómo se usa) y estás brindando los fundamentos para que aprendan cómo utilizar un sistema operativo sin ventanas e incluso comenzar a aprender la forma de trabajo de UNIX.
Tu puedes lograr todo eso (y más) sin tener que pedirles que “confíen en tí” o que se guarden sus preguntas durante dos años, hasta que hayan aprobado su primer curso de POO.
Podrías argumentar que, incluso si java parece más complicado al principio, es más popular y por lo tanto, no puede ser un error enseñarlo. Yo estoy completamente de acuerdo, pero pienso que debería enseñarse como un segundo o tercer lenguaje, no como el primero. Java no solo requiere que el estudiante espere hasta que haya pasado por 2 o 3 cursos de programación antes de poder comprender completamente el lenguaje, sino que, con este enfoque, existen varios conceptos que simplemente no aprenderá nunca, tales como Manejo de Memoria o Punteros.
Así que, en vista de todo esto, si eres un Profesor, dictando un curso de Programación 1 y estás usando Java, te pido sinceramente que lo reconsideres. C no tiene por qué ser difícil y tus estudiantes te agradecerán por brindar un curso completo y autocontenido.

References: resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 resolución