opengl - resueltos - Orden abierto de transformaciones matriciales
transformaciones lineales ejemplos (2)
Digamos que tengo una caja 3D azul (donde el lado superior es de color rojo).
- Ahora llamo glScalef (1, 10, 1).
- Luego llamo glRotatef (90, 0, 1, 0).
- Luego renderizo el cubo.
Lo que esperaba es ver el lado rojo orientado y estirado hacia la pantalla (a lo largo del eje Y del modelo).
Pero lo que estoy viendo es esto: el lado rojo está frente a la pantalla (como se esperaba). Pero el estiramiento se produce en el eje Y del espacio de visualización (no en el modelo).
Sé que si configuro la escala a lo largo del eje Z, obtendré el resultado correcto. Pero mi confusión es que pensé que escalar el eje Y, y luego girar la caja, me daría el resultado correcto.
¿Qué me estoy perdiendo?
OpenGL lee sus matrices en lo que se conoce como orden column major
. El resultado es que cada operación subsiguiente es una pre-multiplicación de todas las operaciones anteriores, no una post-multiplicación. Por lo tanto, cada llamada posterior a una operación OpenGL (glScale, glTranslate, glRotate) es lo primero que afecta a un objeto, y va en orden inverso a como lo escribe.
Entonces, necesitas cambiar tu orden de multiplicación:
glRotatef(90, 0, 1, 0); // Notice how this is the first operation ...
// ... but will be applied after
glScalef(1, 10, 1); // This will be applied first, but is the last operation
// Zany, right?
A decir verdad, se siente menos intuitivo cuando estás escribiendo programas y usando una computadora para tener que especificar cosas en orden inverso. Pero los Graphics Gods That Be decidieron que así es como querían que se comportara la pila de matriz de OpenGL (junto con HLSL, GLSL y otros sistemas: consulte el enlace anterior sobre pedidos de columnas principales).
Si tiene una matriz que representa una matriz 4x4 como esta:
float mat[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
y lo carga en una matriz OpenGL, OpenGL verá los primeros 4 flotantes como la primera columna de la matriz, el segundo 4 flotará como la segunda columna y el tercero 4 flotará como la tercera columna de la matriz, etc., etc.
Entonces, cada 4 carrozas, OpenGL lo ve como otra columna. Esto se conoce como orden de columna mayor. Almacena los datos en columnas. Si tuviera que transponer una matriz de columnas principales, terminaría como una matriz de filas principales, y viceversa.
Como tiene una matriz de columna principal, también necesita usar vectores de columna, lo que significa que su orden de multiplicación será: M * v .
Para demostrarte esto, toma una matriz simple de 2x2 con un vector de columna de 2x1, multiplica como M * v . Deje K = transponer (M), yr = fila vector (1x2).
Entonces M * v = r * K
En pocas palabras, una vez que usa una notación mayor de columna o fila en su código, tiene que apegarse a ella.