我有一个想要使用以下机制移动的对象:左箭头和右箭头改变其旋转,向上箭头增加其位置。 我的问题是,我要么不能围绕自己旋转物体,要么我不能朝被观察的方向移动物体。
绘制功能如下:
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glScalef(SCALE, SCALE, SCALE);
glTranslatef(x, 0, 0);
glRotatef(rotationZ, 0, 0, 1);
glTranslatef(-x, 0, 0);
// Draw the object...
glPopMatrix();
按键检测代码:
case GLUT_KEY_UP:
teclas.up = GL_TRUE;
glutPostRedisplay();
break;
case GLUT_KEY_LEFT:
teclas.left = GL_TRUE;
glutPostRedisplay();
break;
case GLUT_KEY_RIGHT:
teclas.right = GL_TRUE;
glutPostRedisplay();
break;
定时器功能:
if (teclas.up) {
x++;
}
if (teclas.left) {
rotationZ++;
}
if (teclas.right) {
rotationZ--;
}
glutPostRedisplay();
我已经看过多个关于此问题的帖子,我尝试更改x
变量的信号,但似乎没有任何效果。
编辑(解决):
我刚刚将负责向前移动的Timer函数部分更改为:
if (estado.teclas.up) {
homer.x+= (float)cos(homer.rotationZ * M_PI / 180);
homer.y+= (float)sin(homer.rotationZ * M_PI / 180);
}
而且,我的Draw功能:
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glScalef(SCALE, SCALE, SCALE);
glTranslatef(x, 0, 0);
glRotatef(rotationZ, 0, 0, 1);
// Draw the object...
glPopMatrix();
这样,对象总是朝着它面对的方向移动
答案 0 :(得分:1)
这是移动参考框架的问题,这些是关键字。除非你模拟过程的物理过程,否则对于OpenGL渲染,我们不得不担心的是坐标。这里我们有静止的参考框架,有时称为世界框架(特别是如果观察者也相对于它移动),以及连接到物体的移动参考框架(MRF)。 MRF可以相对于世界框架进行任意旋转和平移,有传统方式如何定义。
例如,地球地球MRF定义为地球中心的原点,正X轴与赤道相交,0经线,正Z - 北极,Y与它们互补。对于地球表面上的静点(局部地理坐标),它通常Y指向天顶,正Z指向地平面中的北方,而正X指向东方。在移动车辆的情况下,正Y轴或俯仰轴始终指向其左侧,并且正Z轴或偏航轴始终指向上方,X-滚动轴指向正前方。这个似乎与你的情况相符。
无论轴规格如何,车辆的旋转相当于改变与其对应的矩阵。让我们称之为变换矩阵。在局部坐标中,车速v = {vx,0,0}是与正X轴共线的矢量。但在世界坐标中,它等于
V' = M * v
其中M是MRF的变换矩阵。由于v是每单位时间的坐标变化,因此任何翻译也应遵循此公式。有两种方法可以解决这个问题,如果您使用的是旧版OpenGL,则有两种选择:
首先:您将从身份矩阵开始,并按正确的顺序重新创建所有变换。
glGetFloatv(GL_MODELVIEW_MATRIX, ptr)
)并从中提取偏移量来计算车辆的新位置,了解变换或读取该值。这种方法的缺点是你必须使用OpenGL的函数,其中glTranslate或glRotate的每次调用都会创建另一个与其他矩阵相乘的矩阵(以相反的顺序)。那些过多的数学运算和精确度也不是很好。如果你有几个引用框架,特别是嵌套框架,它可以以中文方式变得非常有趣。
第二种方法是自己进行所有矩阵数学运算,例如使用GLM(glm.h)等数学库和每个参考帧的存储矩阵,在需要时修改或重新生成它们。即使在glLoadMatrix的传统模式下,您也可以直接向OpenGL提供矩阵。如果你担心性能,你应该知道所有现代实现都是在CPU上进行数学运算,GPU不再使用矩阵堆栈了很长时间。通过检查开源实现可以快速找到它。
如果是现代的,灵活的管道,你根本就没有glScale,glTranslate,glRotate。整个矩阵堆栈在OpenGL 3中已弃用。您只能以第二种方式执行此操作,但在这种情况下,您将通过制服为着色器程序提供矩阵。