Programación en Lenguaje Ensamblador

-El Verdadero Lenguaje de las Máquinas-

Programación Gráfica y las Matrices

–La Mecanización de los Cálculos–

Las matrices son una interesante entidad matemática muy relacionada con los juegos 3D. Son cuadros de números que las computadoras modernas pueden procesar mucho mas rápido que las tradicionales expresiones aritméticas de todos los dias. El tema de las matrices llena libros enteros de esos que las únicas palabras que se entienden son “sea”, “tal que” y “entonces”. Así que para no fastidiarlos voy a discutir sobre el tema cuando sea absolutamente necesario. De momento les basta saber que necesitan entender de matrices no solo para hacer programación gráfica sino para poder programar hardware de aceleración 3D como se debe.

En la primera imagen vemos los dos tipos de matrices que vamos a necesitar. Una matriz es un array bidimensional donde cada elemento se localiza por el renglón y la columna en la que se encuentra. En el dibujo los subíndices (los pares de números mas chiquitos) indican el renglón y la columna. Aunque las matrices pueden tener cualquier tamaño, nosotros solo vamos a necesitar las de 4 renglones por 4 columnas para las operaciones de transformación y las de 4 renglones por una columna para los vectores y vértices que vamos a procesar. Antes de ver como se usan las matrices en programación gráfica voy a tratar de explicarles en términos sencillos porqué son tan importantes.

Hasta ahora hemos visto fórmulas aritméticas que transforman gráficos vectoriales por medio de la traslación, rotación y escala. Estas fórmulas son muy diferentes unas de otras y como hemos visto para poner una imagen vectorial en su posición final es necesario aplicar una larga cadena de transformaciones geométricas a una lista aún mas larga de vectores. La complejidad del código para hacer esto así como la enorme cantidad de operaciones es demasiado pesada aún para una computadora muy poderosa. Recuerden que los mundos 3D actuales pueden estar formados por varios millones de polígonos. Pero no se preocupen porque las matrices vienen al rescate.

La primera gran ventaja de las matrices es que son capaces de almacenar secuencias de transformaciones geométricas y luego aplicarlas de un solo golpe. Digamos que para acomodar una figura en un cierto lugar primero tenemos que trasladarla al origen, escalarla, rotarla un cuarto de vuelta y luego colocarla en su posición final. Tendriámos que aplicar esas 4 transformaciones a cada uno de los vectores que forman la imagen en ese orden. Pero si usamos matrices podemos formar una cadena de esas 4 transformaciones y obtener una matriz que pudiera aplicar esas 4 transformaciones a un vector en un solo paso. La cantidad de transformaciones que podemos encadenar en una matriz no tiene mas límite que la pérdida de precisión por parte de los valores flotantes que pueda manejar el sistema. En una matriz podemos meter no solamente transformaciones geométricas, sino también avanzados cálculos de vista de cámara e iluminación. Por no mencionar que los sistemas gráficos actuales son capaces de procesar estas matrices en apenas unos pocos ciclos de reloj.

La segunda ventaja que tienen las matrices es su versatilidad. Basta con crear un par de funciones para procesar matrices en lugar de tener una función para cada transformación geométrica. Esas funciones son la que concatena transformaciones y la que las aplica a los vectores. Aunque existe una matriz diferente para cada tipo de operación gráfica el código que las implementa es siempre el mismo.

Si todos estos argumentos no los convencen, déjenme decirles que la primera vez que me topé con las matrices cuando estudiaba (por mi cuenta) programación gráfica lo primero que pensé fue que era demasiado esfuerzo para el CPU. Luego vi que había muchas formas de implementarlas. La mas sencilla involucra 3 ciclos anidados y ocupa apenas unas 5 lineas de código en C/C++. Esta es la mas tardada. Usando la FPU puede tomar de 50 a 200 lineas pero es mucho mas rápido que la de ciclos anidados en alto nivel. Luego usando la Streaming SIMD Extensions toma unas 30 lineas y se ejecuta en unos 20 ciclos de reloj y finalmente las aceleradoras mas potentes pueden levantar lotes compuestos por millones de matrices y vectores de una sola vez y procesarlos de manera independiente del CPU en un tiempo todavía menor por unidad. Ahora sigamos con un poco de teoría aburrida sobre estas poderosas y cuadradas entidades.

Como Multiplicar Matrices

Lo primero que tenemos que ver es que las matrices son rectangulares. Sus medidas se especifican por la cantidad de renglones y columnas que las componen, pueden ser tan pequeñas como un renglón y una columna o extenderse de manera indefinida. Para referirnos a una matriz completa le ponemos por nombre una letra mayúscula y cuando queremos mencionar un elemento de esa misma matriz escribimos la letra que la nombra en minúscula seguida de los 2 números que indican el renglón y columna separados por una coma. Por ejemplo, si la matriz se llama A el elemento del primer renglón y la segunda columna de esa matriz sería a_1,2. El guión bajo _ es tan solo para que la expresión sea mas sencilla de leer.

Nosotros solo necesitamos matrices de dos tamaños. La primera mide 4 renglones por 4 columnas y es la que almacena y concatena las transformaciones vectoriales. La segunda tiene 4 renglones y una sola columna y guarda las componentes vectoriales o las coordenadas de los vértices según sea el caso. La operación mas importante con matrices es el producto o multiplicación matricial. Para multiplicar dos matrices, la cantidad de columnas de la primera debe de ser igual a la de renglones de la segunda. La matriz que de como resultado el producto va a tener la misma cantidad de renglones de la primera y de columnas que la segunda. Explicado con abejitas y flores, para que dos matrices puedan casarse y tener hijos la cantidad de columnas de la primera debe de ser igual a la de renglones de la segunda y el hijo que tengan va a salir con la cantidad de renglones de la primera y columnas de la segunda. A diferencia de la multiplicación de todos los dias, aquí el orden de los factores SI altera el producto. Es decir que AB es distinto de BA.

La definición seria de la multiplicación de matrices involucra letras griegas, signos raros y subíndices que me da mucha flojera escribir así que lo explicaré con palabras. Si tenemos 2 matrices multiplicables A y B y la matriz C va a ser el producto. Cada elemento de la matriz C es el resultado de la suma de los productos del renglón de la matriz A y la columna B correspondiente. Si saben lo que es un producto escalar no tendrán problemas para entender esto pues la multiplicación de dos matrices de 1 por 4 y 4 por 1 es exactamente la misma que da este producto vectorial. Pero como esto es bastante dificil de entender lo voy a explicar de manera gráfica.

En la segunda imagen se muestra la mejor manera de acomodar las matrices en una hoja para multiplicarlas de manera manual. Primero la hoja se divide en 4 partes iguales.El cuarto de arriba a la izquierda se deja para anotaciones y cálculos intermedios, en el cuarto de abajo a la izquierda se escribe la primera de las matrices que se van a multiplicar. En el cuarto superior derecho la segunda matriz que multiplicaremos y finalmente el cuarto inferior derecho es donde vamos a escribir el resultado. Para que los resultados salgan bien los elementos de las matrices deben de quedar bien alineados. Recuerden que estamos usando papel cuadriculado para hacer esto mas facil. Ahora bien. En el ejemplo del dibujo se multiplican 2 matrices de 4 por 4. Para calcular el primer elemento del resultado correspondiente al primer renglón y primera columna tomamos el primer renglón de la matriz A y la primera columna de la matriz B (aquí encerrados en rojo) y llevamos a cabo la operación de la última imagen. En este caso se escribiría:

(c_1,1) = (a_1,1)*(b_1,1) + (a_1,2)*(b_2,1) + (a_1,3)*(b_3,1) + (a_1,4)*(b_4,1).

El resultado de esta operación se escribe en la posición (c_1,1) y se repite el mismo procedimiento para los otros quince elementos de la matriz C. Recuerden que acomodar las matrices de esta manera permite saber que renglones y columnas de que matriz necesitamos tomar para calcular el resultado de una posición en la matriz C. Solo basta con mirar hacia arriba y a la izquierda del elemento que queremos obtener.

La multiplicación de matrices de 4 por 4 se usa para concatenar transformaciones. Cuando queremos aplicarle una transformación o una cadena de transformaciones (en términos de performance da igual si es una o un millón) a un vector. Repetimos el mismo proceso pero poniendo un vector de 4 renglones por una columna como la segunda matriz. El resultado es una matriz de 4 renglones por una columna cuyos 4 elementos son las componentes del vector ya transformado.

Espero que hayan seguido mi consejo de la entrada anterior y dispongan de una manera rápida de multiplicar matrices. De lo contrario les va a llevar por lo menos media hora multiplicar cada una a mano. En la siguiente entrada veremos como implementar las transformaciones geométricas básicas usando matrices y cuando hayamos visto esto estaremos en posición de entender uno de los conceptos mas importantes de la programación gráfica: La Transformación de Sistemas de Coordenadas. Aunque puede que antes de llegar a eso debamos de ver unas cuantas cosas sobre matrices y vectores en el espacio 3D.

Anuncios

octubre 23, 2011 - Posted by | Uncategorized | , ,

9 comentarios »

  1. jajaja cada vez estamos aprendiendo mas de vos xD pero sigo pensando que hacen falta mas imágenes de ejemplos para las otra entradas

    Comentario por Pavon | octubre 23, 2011 | Responder

  2. y tengo una pregunta.. como nos comunicamos con las tarjetas gráficas para pedir que calculen esos datos? en ASM claro =)

    Comentario por Pavon | octubre 23, 2011 | Responder

    • Las tarjetas graficas trabajan en paralelo con el programa principal, puedes usar por ejemplo funciones de OpenGL que en si no hacen mas que comunicarse con tales dispositivos. Puedes llamar funciones de OpenGL igual que como se hace con la API de Win32. Existe algo llamado GPGPU que consiste en usar el poder de las aceleradoras para lo que te de la gana y no solo algoritmos predefinidos, pero de momento no he leido suficiente al respecto

      Comentario por asm86 | octubre 23, 2011 | Responder

      • pero para comunicarte con las tarjetas gráficas existe alguna interrupción? asi como la int 10h o algo parecido verdad?

        Comentario por Pavon | octubre 23, 2011

      • Si quieres hacer algo muy loco o tus propios drivers para un sistema operativo puedes programarlas hasta por irq y dma, normalmente estos sistemas se manejana traves de llamadas al sistema operativo y dependen de cada uno. En el caso del windows es una simple llamada al sistema, la verdad es que no he programado un sistema de video por interrupciones del BIOS desde los tiempos del VESA 2.0

        Comentario por asm86 | octubre 24, 2011

      • jajaja “algo muy loco” (Y) me gusta

        Comentario por Pavon | octubre 24, 2011

  3. Muy bueno, pues en mi caso con esas 2 fotos lo entendido muy bien, quedaría bien verlo asm + opengl un ejemplo.

    Saludos.
    .:SC:.

    Comentario por strongcod3r | octubre 23, 2011 | Responder

    • Usar OpenGL desde ensamblador es exactamente igual que cualquier otra API de Windows. Incluso es mas sencillo desde ensamblador trabajar con OpenGL que con DirectX. En el fasm viene un ejemplo de opengl ya hecho, solo busca las funciones adecuadas y listo.

      Comentario por asm86 | octubre 23, 2011 | Responder

  4. Esta muy bien eehhh me gusta las razones de matrices

    Comentario por hugo stalyn vega chiguano | marzo 18, 2014 | Responder


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: