围绕自身旋转物体

时间:2016-12-21 14:32:34

标签: c++ opengl

我有一个想要使用以下机制移动的对象:左箭头和右箭头改变其旋转,向上箭头增加其位置。 我的问题是,我要么不能围绕自己旋转物体,要么我不能朝被观察的方向移动物体。

绘制功能如下:

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();

这样,对象总是朝着它面对的方向移动

1 个答案:

答案 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,则有两种选择:

首先:您将从身份矩阵开始,并按正确的顺序重新创建所有变换。

  1. 设置单位矩阵。
  2. 按所需值翻译(在本地电线中)
  3. 应用车辆旋转
  4. 按车辆最后已知位置的值进行翻译。
  5. 通过从OpenGL获取矩阵(glGetFloatv(GL_MODELVIEW_MATRIX, ptr))并从中提取偏移量来计算车辆的新位置,了解变换或读取该值。
  6. 这种方法的缺点是你必须使用OpenGL的函数,其中glTranslate或glRotate的每次调用都会创建另一个与其他矩阵相乘的矩阵(以相反的顺序)。那些过多的数学运算和精确度也不是很好。如果你有几个引用框架,特别是嵌套框架,它可以以中文方式变得非常有趣。

    第二种方法是自己进行所有矩阵数学运算,例如使用GLM(glm.h)等数学库和每个参考帧的存储矩阵,在需要时修改或重新生成它们。即使在glLoadMatrix的传统模式下,您也可以直接向OpenGL提供矩阵。如果你担心性能,你应该知道所有现代实现都是在CPU上进行数学运算,GPU不再使用矩阵堆栈了很长时间。通过检查开源实现可以快速找到它。

    如果是现代的,灵活的管道,你根本就没有glScale,glTranslate,glRotate。整个矩阵堆栈在OpenGL 3中已弃用。您只能以第二种方式执行此操作,但在这种情况下,您将通过制服为着色器程序提供矩阵。