计算gluLookAt,glOrtho和glFrustum

use*_*699 2 c++ opengl math 3d

我正在进行绘制线框GLUT标准对象的任务.这看起来很简单,但我们被告知我们不能使用gluAtLook(),glOrtho(),glFrustrum,但我们必须使用glTranslate(),glScale()和glRotate.如何在不使用glMatrixMode(GL_PROJECTION)中的这些函数的情况下投影对象?

这是我到目前为止:

#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <math.h> // for sqrt()
#include <glut.h>


void init(void)
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0, 1.0, 1.0);
    glLoadIdentity();             /* clear the matrix */
    /* viewing transformation  */
    glTranslatef(0.0, 0.0, -5.0);
    glScalef(1.0, 2.0, 1.0);      /* modeling transformation */
    glutWireCube(1.0);
    glFlush();

}

void reshape(int w, int h)
{
    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
    //glTranslatef(0.0, 0.0, -5.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(500, 500);
    glutInitWindowPosition(100, 100);
    glutCreateWindow(argv[0]);
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMainLoop();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

有人可以帮忙吗?

leg*_*s2k 7

我们被告知我们不能使用gluAtLook(),glOrtho(),glFrustrum但我们必须使用glTranslate(),glScale()和glRotate

gluLookAt建立世界观看空间变换,glOrtho观察正投影空间变换,glFrustum观察透视投影空间变换.当你说你的导师不允许使用它时,它显然意味着目的是要了解这些功能如何起作用.

互联网上有很多资源可以告诉你.是着名的加州大学伯克利分校教授Ravi Ramamoorthi博士的作品.SongHo有很好的文章可以帮助你做同样的事情.


我可以在2D中演示一个简单的案例.假设我们有一个用对象定义的世界(为简单起见,我们采用P点); 我们希望相机处于(3,3),其X和Y轴指向与世界X和Y轴相反的方向.为简单起见,我们假设两个帧具有相同的缩放因子,即X和Y方向上的1个单位测量两个系统的相同距离(幅度).因此,两个帧仅因方向和原点位置而不同(W 0和V 0是表示它们的符号).

我们需要导出M world-> view,即将世界空间中的点映射到视图空间的矩阵.这就是现在不推荐使用的gluLookAt函数计算并乘以GL_MODELVIEW矩阵堆栈.该矩阵将用于从相机的角度看世界.

我们知道 M world-> view = T view-> world.将帧A的点映射到帧B的矩阵也将是将B的帧变换为A的帧的矩阵.推导是这样的

逐步将视图框架转换为世界框架

世界上的点P有(1,2)= P w作为坐标,我们有效地找到一个矩阵,当乘以P w时,它将得到P v,即视图帧中的相同点的坐标.该点被写为3D点,因为2D点的均匀扩展将是3D点; 齐次坐标为1,因为它是一个点; 如果它是一个矢量,那就是0.

第一步是轮换; 旋转视图的框架-180°(右旋系统+ ve旋转逆时针); 现在,两个帧的轴都沿着相同的方向.我们要解决原点差异,这是通过翻译完成的,这是第2步.将两者相乘将得到所需的矩阵.请注意,每个步骤通过后乘法将视图的帧更接近世界的帧.此外,每个转换都基于我们所在的当前本地帧,而不是基于起始全局(世界)帧.

同样的想法也可以扩展到3D,需要更多努力.在上面的推导中我只需要旋转矩阵,平移矩阵和矩阵乘法; 不gluLookat.我给你的链接应该有助于计算相同的3D.投影矩阵推导更复杂一些.但是,您仍然可以在不使用的情况下实现结果glOrtho; 我上面给出的链接有最终矩阵的公式; 您可以使用它来组合矩阵并将其乘以GL_PROJECTION矩阵堆栈.

注意:上面的推导假定了列向量,因此转换矩阵(如旋转)和乘法顺序基于此完成.如果你假设行向量约定,那么转置所有矩阵并反转乘法的顺序,因为

(AB)^ T = B ^ TA ^ T.