Viendo como OpenGL va a deprecar parte del API (cosa que me parece bien, a ver si conseguimos mejores drivers!), y la costumbre de programar cosas de mas que tenemos algunos, he creído que alguien le seria útil. Funcionan 100% igual que las funciones de la API (misma matriz, etc). Empezaré por el mas trivial (la implementación es directa respecto a la documentación), crear una matriz de proyección ortográfica, con los mismos parámetros que gluOrtho:
1: CMatrix4x4 CreateOrtographicProj (float left, float right,
2: float bottom, float top,
3: float Near, float zFar)
4: { 5: CMatrix4x4 result; 6:7: float tx = -(right+left)/(right-left),
8: ty = -(top+bottom)/(top-bottom), 9: tz = -(zFar+zNear)/(zFar-zNear); 10: 11: result.Set (2.f/(right-left), 0.f, 0.f, tx, 12: 0.f, 2.f/(top-bottom), 0.f, ty, 13: 0.f, 0.f, -2.f/(zFar-zNear), tz, 14: 0.f, 0.f, 0.f, 1.f); 15:16: return result;
17: }
Como apunte, en todos los snippets de codigo usan ciertas clases matemáticas sencillas que uso, en esta la clase matriz cuadrada de 4 elementos. Si hay alguna duda sobre esto, comentadlo y expando los detalles sobre ellas. A efectos prácticos, podéis suponer que CMatrix4x4::Set (...) es equivalente a ir asignando a un array de floats de 16 elementos: el primer parámetro seria el primer elemento del array, el segundo parámetro el segundo elemento, etc.
En segundo lugar, proyección en perspectiva, equivalente a gluPerspective:
En segundo lugar, proyección en perspectiva, equivalente a gluPerspective:
1: CMatrix4x4 CreatePerspectiveProj (float fovy, float aspect,
2: float zNear, float zFar)
3: {4: float f = tanf (((fovy/180.f)*(float)M_PI) / 2.0f);
5: float div = (zNear-zFar);
6: 7: f = IsFloatEqual(f, 0.f) ? FLT_MAX : 1.f / f; 8: div = IsFloatEqual(div, 0.f) ? FLT_MAX : 1.f / div; 9: 10: CMatrix4x4 result; 11: 12: result.Set (f / aspect, 0.f, 0.f, 0.f, 13: 0.f, f, 0.f, 0.f, 14: 0.f, 0.f, (zFar+zNear)*div, (2.f*zFar*zNear)*div, 15: 0.f, 0.f, -1.f, 0.f); 16:17: return result;
18: }
A comentar, la macro IsFloatEqual solo compara dos números en coma flotante: el método normalmente mas recomendado (pero menos rápido, obviamente), es restarlos, coger el valor absoluto, y comparar si es menor que cierto epsilon. Esto se hace así debido a que por precisión de los numeros en coma flotante, comparar con numeros exactos (por ejemplo, haciendo float == 0.0) es desaconsejable.
Finalmente, el que tiene mas curro, el gluLookAt (sobretodo, porque la documentación obvia ciertos detalles):
Finalmente, el que tiene mas curro, el gluLookAt (sobretodo, porque la documentación obvia ciertos detalles):
1: CMatrix4x4 CreateLookAt (const CVector3 &eye,
2: const CVector3 ¢er,
3: const CVector3 &up)
4: { 5: CVector3 f (center-eye); 6: CVector3 upLocal(up); 7: 8: f.Normalize(); 9: upLocal.Normalize(); 10: 11: CVector3 s = f ^ upLocal; 12: CVector3 u = s ^ f; 13: 14: s.Normalize(); 15: u.Normalize(); 16: 17: CMatrix4x4 result, translate; 18: 19: result.Set ( s.x, s.y, s.z, 0.f, 20: u.x, u.y, u.z, 0.f, 21: -f.x, -f.y, -f.z, 0.f, 22: 0.f, 0.f, 0.f, 1.f); 23: 24: translate.SetTranslation (eye*-1.f); 25:26: return result*translate;
27: }A ver, destacar de este snippet, que el operador^ de la clase CVector3 equivale a hacer un producto vectorial (cross product), que el método Normalize hace lo inferible del nombre (es decir, normaliza el vector usando su modulo), y que el método SetTranslation de la clase CMatrix4x4, simplemente asigna a una traslación a la matriz (en este caso, al ser una matriz identidad, simplemente creamos una matriz de traslación).
No he explicado a fondo que hace cada parte, para eso tenéis los links a la documentación de OpenGL, y si hay mas preguntas mejor dejad comentarios.
La licencia de este código es la obvia y clásica haced lo que os dé la gana con él. Si encontrais algun bug, comentarlo y aprendemos todos de ello :)
No he explicado a fondo que hace cada parte, para eso tenéis los links a la documentación de OpenGL, y si hay mas preguntas mejor dejad comentarios.
La licencia de este código es la obvia y clásica haced lo que os dé la gana con él. Si encontrais algun bug, comentarlo y aprendemos todos de ello :)

























