2011-03-04 92 views
0

我试图从NEHEs教程中了解lesson 9,这是关于在3d空间中移动位图的。OpenGL:了解转换

这里最有趣的事情是通过3d空间将2D位图纹理移动到简单的四边形上,并始终保持其面向屏幕(查看器)。因此,位图看起来像3d,但无论3D空间中的哪个位置,它都始终面向观看者。

在第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,这到底是怎么转动?再次是坐标系,观察者本身?

在一个真实的世界。我会某处放置星在三维空间中,然后在我的世界本源世界空间中旋转,然后做的明星再次移动到原点,并开始在边缘移动,那我就做了一个旋转明星本身就是面向观众的。我想这是在这里完成的。但是,我如何首先围绕世界起源旋转,然后绕着这个明星本身旋转呢?对我来说,看起来像opengl是在世界坐标系统和目标坐标系统之间切换的,它并不像你看到的那样真正发生。

我不需要添加代码的其余部分,因为它非常标准。简单的GL初始化为3D图纸,旋转的东西,然后使用混合使用星形纹理简单地绘制QUADS。而已。

有人能解释IM误会的是什么?

+0

在OpenGL中,约定是旋转原点处的对象,然后将其转换为需要去的地方。这基本上模拟了“局部坐标”旋转。 请记住,这一切都发生在一个堆栈上,所以顺序很重要!此代码将围绕对象的局部轴执行两次旋转,然后将其翻译出来,然后再做两次旋转和平移(有效地转换世界坐标)。 – fjlksahfob 2011-03-04 22:44:19

回答

4

另一种考虑gl矩阵堆栈的方法是从绘图调用中向后走。在你的情况下,由于你的画是最后一行,让我们加深代码:

1)首先,星星围绕X轴旋转 - 相对于原点。

2)恒星相对于原点围绕Y轴旋转-star [loop] .angle。

3)恒星沿着X轴向下移动。

4)恒星相对于原点围绕Y轴旋转了星形[loop] .angle。由于步骤3,恒星不再处于原点,因此该旋转既移动了恒星的中心,又将其旋转到本地。

5)恒星相对于原点围绕X轴倾斜旋转。 (相同注4)

6)恒星通过缩放单位向下移动Z轴。

这里的诀窍很难输入文字,但尝试和描绘移动的顺序。虽然步骤2和步骤4可能看起来像是相互颠倒的,但它们之间的移动会改变旋转的性质。关键在于旋转是围绕原点定义的。移动星星会改变旋转的效果。

当你想旋转某个东西时,这会导致堆叠矩阵的典型用法。首先你将它移动到原点,然后旋转它,然后将其移回。你在这里有几乎相同的概念。

我发现用两只手来显示矩阵很有用。保持一只手来表示原点,第二个(通常是右手,如果你在像OpenGL这样的右手坐标系中)代表对象。我像XYZ轴一样展开我的手指,以便我可以在本地以及原点周围看到旋转。像这样开始,围绕原点的旋转序列和线性移动应该更容易描绘。

您问的第二个问题与相机矩阵在典型的OpenGL设置中的表现有关。首先,了解屏幕空间坐标的概念(类似于设备坐标)。这是实际显示的空间。 X和Y是屏幕的矢量,Z是深度。该空间通常在-1到1的范围内。向下移动对象可有效移动对象。

相机(或透视矩阵)通常负责将'World'空间转换为此屏幕空间。这个矩阵定义了'查看器',但最后它只是另一个矩阵。该矩阵总是应用于'最后',所以如果您正在像前面描述的那样向上读取变换,则相机通常位于最上方,就像您看到的那样。在这种情况下,您可以将最后一次转换(通过缩放转换)视为一个非常简单的相机矩阵,通过缩放单位将相机移回。

祝你好运。 :)

+0

很好的回答。谢谢尼克。评论中的第4点很有趣。因为我移动了第3点中的恒星,所以旋转行为发生了变化,并在本地旋转了恒星。只是看到了步骤,现在它是有道理的。 Yeeeh。 :-D – NovumCoder 2011-03-04 23:26:36

+1

我花了几年教导入图形。 :)欢迎。 – 2011-03-04 23:28:42

1

的的glTranslatef在中间受到影响由旋转:它移动星形沿轴x“至距离Dist和轴x”是在比原始x轴线时间由(倾斜+角度)旋转。

在opengl中你有对象坐标乘以(投影矩阵的堆栈)。所以你在移动物体。如果您想“移动摄像机”,则必须通过摄像机位置和坐标轴的逆矩阵来代替:

ProjectedCoords = CameraMatrix^-1。 ObjectMatrix。 ObjectCoord

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中很重要。

从技术角度而言,我的描述可能并不完美,但适用于我。