我试图从NEHEs教程中了解lesson 9,该教程是关于在3d空间中移动的位图。
这里最有趣的事情是将2d位图纹理移动到简单的四边形到3d空间,并始终面向屏幕(查看器)。所以位图看起来是3d,但无论它在3d空间中的哪个位置,它都是面向观察者的2d。
在第9课中,生成一个圆形的星星列表,看起来非常好。为了避免从侧面看到恒星,编码器正在进行一些棘手的编码,以使恒星始终面向观察者。
这个代码如下:(为循环中的每个星调用以下代码)
glLoadIdentity();
glTranslatef(0.0f,0.0f,zoom);
glRotatef(tilt,1.0f,0.0f,0.0f);
glRotatef(star[loop].angle,0.0f,1.0f,0.0f);
glTranslatef(star[loop].dist,0.0f,0.0f);
glRotatef(-star[loop].angle,0.0f,1.0f,0.0f);
glRotatef(-tilt,1.0f,0.0f,0.0f);
在上面的线条之后,星星的绘图开始了。如果检查最后两行,您会看到第3行和第4行的转换刚刚被取消(如撤消)。最后这两条线让我们有可能让恒星始终面向观众。但我不知道为什么会这样。
我认为这来自于我对OpenGL如何真正进行转换的误解。 对我来说,最后两行就像撤消以前所做的一样,对我来说,没有意义。但它的工作。
所以当我调用glTranslatef时,我知道视图的当前矩阵乘以glTranslatef提供的转换值。 换句话说“glTranslatef(0.0f,0.0f,zoom);”如果缩放为负,我会移动我要将我的星星绘制到场景的地方。行。
但是这里究竟是什么?观察者是“移开”还是某种物体坐标系统被glTranslatef移动到场景中?这是怎么回事?
那么glRotatef,旋转的是什么?再一个坐标系,观众本身?
在现实世界中。我会将星星放置在3d空间的某个地方,然后在我的世界原点周围的世界空间中旋转它,然后当星星移动到原点并再次从边缘开始时进行移动,然后我会做一个旋转明星本身因此面向观众。我想这是在这里完成的。但是我如何首先围绕世界起源旋转,然后围绕恒星本身?对我来说,看起来opengl正在世界坐标系统和对象坐标系统之间切换,而这并不像你看到的那样真正发生。
我不需要添加其余代码,因为它非常标准。简单的GL初始化为3D绘图,旋转的东西,然后简单绘制QUADS与星形纹理使用混合。多数民众赞成。
有人可以在这里解释我的误解吗?
答案 0 :(得分:4)
另一种思考gl矩阵堆栈的方法是从你的绘制调用向上,向后走。在你的情况下,由于你的抽奖是最后一行,让我们加强代码:
1)首先,相对于原点,恒星围绕X轴旋转-tilt。
2)恒星绕着Y轴旋转-star [loop]。相对于原点。
3)星星被[星环]向下移动。沿X轴向下移动。
4)恒星围绕Y轴旋转,相对于原点绕Y轴旋转。由于步骤3中星星不再处于原点,因此该旋转既可以移动恒星的中心,也可以在本地旋转。
5)相对于原点,围绕X轴倾斜旋转星形。 (与4相同)
6)通过缩放单位向下移动星号。
这里的诀窍很难输入文字,但是尝试并描绘移动的顺序。虽然步骤2和4看起来可能相互颠倒,但它们之间的移动会改变旋转的性质。关键短语是旋转是围绕原点定义的。移动星形会改变旋转的效果。
当您想要就地旋转某些东西时,这会导致堆叠矩阵的典型使用。首先将它移动到原点,然后旋转它,然后将其移回原点。你在这里拥有的是几乎相同的概念。
我发现使用双手来显示矩阵是有用的。保持一只手代表原点,第二只(如果你是一个像OpenGL这样的右手坐标系,通常是右边)代表对象。我像XYZ轴一样张开手指,我可以在局部和原点周围看到旋转。从这样开始,原点周围的旋转顺序和线性移动应该更容易描绘。
您提出的第二个问题涉及相机矩阵在典型OpenGL设置中的行为方式。首先,了解屏幕空间坐标的概念(类似地,设备坐标)。这是实际显示的空间。 X和Y是屏幕的矢量,Z是深度。空间通常在-1到1的范围内。将对象向下移动Z可以有效地移动对象。
相机(或透视矩阵)通常负责将“世界”空间转换为此屏幕空间。这个矩阵定义了'viewer',但最后它只是另一个矩阵。矩阵始终应用于“最后”,因此如果您正如我之前所述向上读取变换,则相机通常位于顶部,就像您所看到的那样。在这种情况下,您可以将最后一个变换(通过缩放平移)视为一个非常简单的相机矩阵,通过缩放单位向后移动相机。
祝你好运。 :)答案 1 :(得分:1)
中间的glTranslatef受到旋转影响:它将恒星沿x'轴移动到距离dist,而轴x'在此时旋转(倾斜+角度)与之相比原始的x轴。
在opengl中,您有对象坐标乘以(一堆)投影矩阵。所以你正在移动物体。如果你想“移动一个摄像机”,你必须通过摄像机位置和轴的逆矩阵多次显示:
ProjectedCoords = CameraMatrix ^ -1。 ObjectMatrix。 ObjectCoord
答案 2 :(得分:0)
我也发现这非常令人困惑但我只是玩了一些NeHe代码以更好地理解glTranslatef()和glRotatef()。
我目前的理解是glRotatef()实际上旋转了坐标系,因此glRotatef(90.0f,0.0f,0.0f,1.0f)将使x轴成为y轴之前的位置。旋转后,glTranslatef(1.0f,0.0f,0.0f)将在屏幕上向上移动一个对象。
因此,glTranslatef()根据坐标系的当前旋转移动对象。因此,glTranslatef和glRotatef的顺序在教程9中很重要。
在技术方面,我的描述可能并不完美,但它对我有用。