计算 gluLookAt、glOrtho 和 glFrustum [英] Calculating gluLookAt, glOrtho and glFrustum

查看:21
本文介绍了计算 gluLookAt、glOrtho 和 glFrustum的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am working on an assignment to draw wire frame GLUT standard objects. This seems simple but we are told we cannot use gluAtLook(), glOrtho(), glFrustrum but we must use glTranslate(), glScale() and glRotate. How to you project the object without using these functions in 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;
}

有人可以帮忙吗?

推荐答案

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

we are told we cannot use gluAtLook(), glOrtho(), glFrustrum but we must use glTranslate(), glScale() and glRotate

gluLookAt 设置世界以进行视图空间转换,glOrtho 进行视图到正交投影空间的转换,glFrustum 进行视图到透视投影空间的转换转型.当你说你的导师不允许使用它时,这显然意味着首先要了解这些功能是如何工作的.

gluLookAt sets up the world to view space transformation, glOrtho does view to orthographic projection space transformation and glFrustum does view to perspective projection space transformation. When you say your tutor hasn't allowed to use it, it clearly means that the intention is to understand how these functions work in the first place.

互联网上有很多资源可以教您这一点.这是一个,作者是加州大学伯克利分校著名教授 Ravi Ramamoorthi 博士.SongHo 有好文章,可以帮助您做同样的事情.

There're many resources on the internet which teach you that. Here's one by a renowned UC Berkeley professor Dr. Ravi Ramamoorthi. SongHo has good articles which will help you do the same thing.

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

I can demonstrate a simple case in 2D. Say we've a world defined with objects (for simplicity we take a point P); we want the camera to be at (3, 3) with its X and Y axes pointing in directions opposite to world's X and Y axes. For simplicity we'll assume both frames have the same scaling factor i.e. 1 unit in both X and Y directions measure the same distance (magnitude) for both systems. So the two frames differ only by orientation and origin location (W0 and V0 are the symbols denoting them).

我们需要推导出 Mworld->view 即世界空间中的点映射到视图空间的矩阵.这是现已弃用的 gluLookAt 函数计算并与 GL_MODELVIEW 矩阵堆栈相乘的内容.该矩阵将用于从相机的视角获取世界视图.

We need to derive Mworld->view i.e. the matrix which maps points in world space to view space. This is what the now-deprecated gluLookAt function calculates and multiplies with GL_MODELVIEW matrix stack. This matrix will be used to get a view of the world from the camera's viewpoint.

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

We know that Mworld->view = Tview->world. The matrix which maps points of frame A to frame B will also be the matrix which transforms B's frame into A's frame. The derivation goes like this

世界中的点 P 有 (1, 2) = Pw 作为坐标,我们有效地找到了一个矩阵,当乘以 Pw 将给出Pv 即同一个点在视图框中的坐标.该点被写为 3D 点,因为 2D 点的齐次扩展将是 3D 点;齐次坐标将为 1,因为它是一个点;如果是向量,则为 0.

The point P in world has (1, 2) = Pw as coordinates, we're effectively finding a matrix, which when multiplied with Pw will give Pv i.e. the same point's coordinates in view frame. The point is written as a 3D point since homogeneous extension of a 2D point would be a 3D point; the homogeneous coordinate would be 1 since it's a point; had it been a vector, it'd be 0.

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

Step one is rotation; rotating view's frame by -180° (right-handed system where +ve rotation is counter-clockwise); now the axes are along the same direction for both frames. We've to tackle the origin difference, this is done by translation, which is step 2. Multiplying both will give the required matrix. Note that each step transforms the view's frame more closer into world's frame by post-multiplying. Also each transformation is based on that current local frame we're in and not based on the starting global (world) frame.

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

The same idea can be extended to 3D too, with some more effort. In the above derivation all I needed were just rotation matrix, translation matrix and matrix multiplication; no gluLookat.The links I gave you should help in calculating the same for 3D. The projection matrix derivation is a bit more involved. However, you can still achieve the result without using glOrtho; the links I gave above has the formula for the final matrix; you can compose a matrix using that and multiply that to the GL_PROJECTION matrix stack.

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

Note: The above derivation assumes column vectors and thus transformation matrices (like rotation) and multiplication order are done based on that. If you assume row vector convention then transpose all the matrices and reverse the order of multplication since

(AB)^T = B^T A^T

(AB)^T = B^T A^T

这篇关于计算 gluLookAt、glOrtho 和 glFrustum的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆