我正在编写一个OpenGL应用程序(C#和OpenTK),我对OpenGL转换的工作原理感到困惑。
我设置了一个透视投影,我在默认位置使用默认方向(+ X向右,+ Y向上,+ Z向我。)现在我在XY平面绘制一个四边形,在Z轴上-10。
GL.Begin(PrimitiveType.Quads);
GL.Color3(Color.Green);
GL.Vertex3(-1, 1, -10);
GL.Vertex3(1, 1, -10);
GL.Vertex3(1, -1, -10);
GL.Vertex3(-1, -1, -10);
GL.End();
这可以按预期工作。但是现在我想沿它的局部 Y轴旋转四边形,所以我添加了一个旋转,它被应用到我的单位矩阵。这是代码的相关部分:
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();
GL.Rotate(10, 0, 1, 0);
GL.Begin(PrimitiveType.Quads);
GL.Color3(Color.Green);
GL.Vertex3(-1, 1, -10);
GL.Vertex3(1, 1, -10);
GL.Vertex3(1, -1, -10);
GL.Vertex3(-1, -1, -10);
GL.End();
但是这将围绕我的“世界”Y轴旋转飞机,所以现在飞机不再穿过我的-Z轴了,但它是一个角度。
如何将物体保持在所需的位置(沿着我的Z轴在-10处)但是它绕自己的轴旋转?
我已经尝试过第一次转换到原点,执行旋转,绘图,然后向后移动,但这也不起作用,大概是因为一旦我旋转,现在我不再沿着“世界”进行翻译“轴,但旋转的轴。这是代码:
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();
GL.Translate(0, 0, 10);
GL.Rotate(10, 0, 1, 0);
GL.Begin(PrimitiveType.Quads);
GL.Color3(Color.Green);
GL.Vertex3(-1, 1, -10);
GL.Vertex3(1, 1, -10);
GL.Vertex3(1, -1, -10);
GL.Vertex3(-1, -1, -10);
GL.End();
GL.Translate(0, 0, -10);
我有一种感觉,我需要使用PushMatrix
和PopMatrix
,但我不太清楚我是否理解他们是如何发挥作用的。如果我在执行任何操作之前推动我的矩阵,然后弹出它,我的视图是否应该恢复正常?如果是这样,为什么这不起作用:
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();
// Push current matrix onto the stack
GL.PushMatrix();
// Perform operations on newly pushed matrix
GL.Translate(0, 0, 10);
GL.Rotate(10, 0, 1, 0);
GL.Begin(PrimitiveType.Quads);
GL.Color3(Color.Green);
GL.Vertex3(-1, 1, -10);
GL.Vertex3(1, 1, -10);
GL.Vertex3(1, -1, -10);
GL.Vertex3(-1, -1, -10);
GL.End();
// Pop it off, so return to my previous matrix
GL.PopMatrix();
答案 0 :(得分:3)
你的第二次尝试是在正确的轨道上,但它仍然错过了几个方面:
glEnd()
之后进行翻译将无能为力。代码序列将如下所示:
GL.Translate(0, 0, -10);
GL.Rotate(10, 0, 1, 0);
GL.Translate(0, 0, 10);
GL.Begin(PrimitiveType.Quads);
...
GL.End();
此代码示例中不需要PushMatrix()
和PopMatrix()
,因为您在绘制函数的开头调用LoadIdentity()
,这会将当前转换恢复为标识转换。至少根据显示的内容,您不会在此代码之后绘制任何内容,因此无需恢复以前的矩阵。
另一种方法是不为每一帧调用LoadIdentity()
,而是将上面的代码段括在开头的PushMatrix()
和最后的PopMatrix()
。这实际上更具可扩展性,因为如果需要,它会恢复矩阵以进行额外的渲染。
我在这里回答类似问题时更详细地解释了一些内容:Rotating an object around a fixed point using glMultMatrix。