我们被告知不能使用 gluAtLook()、glOrtho()、glFrustrum,但必须使用 glTranslate()、glScale() 和 glRotate
gluLookAt
设置世界来观看空间变换,glOrtho
确实考虑到正交投影空间变换和glFrustum
确实查看到透视投影空间变换。当你说你的导师不允许使用它时,这显然意味着你的目的是首先了解这些功能是如何工作的。
互联网上有很多资源可以教您这些知识。这是一个由加州大学伯克利分校著名教授 Ravi Ramamoorthi 博士撰写。宋浩有好文章这将帮助您做同样的事情。
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).
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.
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
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。将两者相乘将得到所需的矩阵。请注意,每一步都会将视图的框架转换为更接近世界的框架后乘法。此外,每个转换都基于我们所处的当前局部框架,而不是基于起始全局(世界)框架。
同样的想法也可以扩展到 3D,但需要付出更多的努力。在上面的推导中,我所需要的只是旋转矩阵、平移矩阵和矩阵乘法;不gluLookat
.我给您的链接应该有助于计算 3D 的相同值。投影矩阵的推导有点复杂。但是,您仍然可以在不使用的情况下获得结果glOrtho
;我上面给出的链接有最终矩阵的公式;您可以使用它组成一个矩阵并将其乘以 GL_PROJECTION 矩阵堆栈。
Note:上述推导假设列向量,因此变换矩阵(如旋转)和乘法顺序是基于此完成的。如果您假设行向量约定,则转置所有矩阵并反转乘法的顺序,因为
(AB)^T = B^T A^T