如何在OpenGL中获取对象的坐标

rjs*_*rjs 8 opengl

我希望能够在翻译和旋转之后获得对象(例如三角形)的坐标,我想这样做的原因是以后我可以进行碰撞检测并使用坐标计算对象之间的距离.我想我可能不得不使用gluProject但不确定.还有不同坐标空间之间的差异,例如世界,物体等.

我在它下面有一些代码是一个正方形中间的圆圈,我怎么能检测到圆圈接触其中一个边缘时,我可以使用向上,向下,向左,向右键移动它只是改变x或y坐标,但我只想做一些基本的碰撞检测,我不知道该怎么做.

glPushMatrix();
    glColor3f(0.0f, 1.0f, 0.0f);
    glTranslatef(0.0f, 0.0f, -5.0f);

    glScalef(0.5f, 0.5f, 0.0f);
    glBegin(GL_POLYGON); 
        glVertex3f(-5.0f, -5.0f, 0.0f);
        glVertex3f(5.0f, -5.0f, 0.0f);
        glVertex3f(5.0f, 5.0f, 0.0f);
        glVertex3f(-5.0f, 5.0f, 0.0f);
    glEnd();
glPopMatrix();

glPushMatrix();


    glColor3f(1.0f, 0.0f, 0.0f);
    glTranslatef(x, y, -20.0f);

    glBegin(GL_POINTS);
        glVertex3f(-5, -5, 10.0f);
    glEnd();

    GLUquadricObj *qobj = gluNewQuadric();
    gluQuadricDrawStyle(qobj, GLU_FILL);
    gluSphere(qobj, 1.0f, 20, 20);
    gluDeleteQuadric(qobj);
glPopMatrix();
Run Code Online (Sandbox Code Playgroud)

Kos*_*Kos 11

还有不同坐标空间之间的差异,例如世界,物体等.

这主要是一个惯例问题,但是:

  • 模型空间(=局部空间)是特定模型相对于其"中心"的坐标空间.如果你有一个带有模型的文件,坐标会围绕它的某个点(例如它的几何中心,它的底部,实际上是任何东西).

  • 场景空间(=世界空间)是相对于场景的任意点的坐标空间

  • 眼空间(=视图空间)是在相机是在点的空间(0,0,0),x面临右,y面朝上和z面向屏幕(-z=更深)

  • 剪辑空间(-1,-1,*)视口左下角的位置,(1,1,*)是视口的右上角,(-1,1)中的Z坐标仅表示深度(再次更小Z =更深).(片段

  • 屏幕空间(=窗口坐标)与上面相同,只是坐标从-1..1基于像素的值重新调整为匹配当前视口和深度范围的范围.

通过将(在OpenGL约定中通常为左乘)乘以模型矩阵(其中包含模型在场景中的位置的信息),将坐标从模型空间转换为场景空间.如果你有一个场景层次结构,对象可以有许多"堆叠"的模型矩阵(剑相对于手臂的放置,相对于骑士的手臂,相对于场景的骑士).

然后通过乘以视图矩阵(通常连接到"相机"对象)将坐标转换为眼睛空间.

之后,使用投影矩阵将这些坐标转换为屏幕空间,以便OpenGL将这些坐标映射到实际的屏幕像素(取决于视口设置).

一些事实:

  • 模型和视图矩阵通常包含平移,旋转和/或缩放,而投影矩阵通常包含透视变换,这使得远离屏幕的对象看起来更小.

  • 旧OpenGL(2.x及更早版本)要求您将矩阵放在两个"矩阵堆栈"上:

    • GL_MODELVIEW堆栈应包含View*Model(或View*Model1*Model2 ...*ModelN),
    • GL_PROJECTION堆栈只能包含Projection矩阵.

这些也可以是单个矩阵,而不是堆栈,但是引入了堆栈(以及glPushMatrixglPopMatrix),让程序员可以轻松地"保存和加载"它们.在计算中仅使用每个堆栈中的"最顶层"矩阵.

投影矩阵通常用gluPerspective等价物创建.视图矩阵可以用制成gluLookAt(或类似的模型矩阵),并且模型矩阵可以使用容易地组装glTranslate,glRotateglScale.

(注意:OpenGL 3.1+删除了这些功能,允许您使用任何矩阵和您喜欢的任何约定)


知道:

我希望能够在翻译和旋转后得到一个物体(例如三角形)的坐标,我想这样做的原因是以后我可以进行碰撞检测并使用坐标计算物体之间的距离

计算所有物理的合理方法是在场景空间中进行.

因此,如果你有一个模型(例如一个三角形网格),要获得它在场景空间中任何顶点的位置,你需要只将它乘以模型的模型矩阵(或者在层次结构的情况下,通过它的所有模型)矩阵).


关于gluProject,如果您想知道 - 这是一种方便的方法,它允许您将一组坐标乘以当前PROJECTION*MODELVIEW并执行视口转换以查看它最终会在屏幕空间中的位置,并gluUnProject执行相反的操作.

参考:http://www.opengl.org/resources/faq/technical/transformations.htm