0

我知道 StackOverflow 充满了类似的问题(比如这个那个),但给出的解决方案似乎对我不起作用。我的目标是用来gluProject从 3D 空间中获取某个点的屏幕坐标。在此之前,我希望通过执行以下操作来获取矩阵:

GLint view[4]={0};
GLdouble proj[16]={0};
GLdouble model[16]={0};

glGetDoublev(GL_PROJECTION_MATRIX,proj);
glGetDoublev(GL_MODELVIEW_MATRIX,model);
glGetIntegerv(GL_VIEWPORT,view);

知道这三个允许计算点的屏幕坐标。然而,当我调用这些函数时,我得到了奇怪的结果:

VIEWPORT
       0                0                1366               768

PROJECTION
-536 870 912     1 073 460 858           0                  0
      0                0           -536 870 912       1 073 460 858
      0                0                 0                  0
      0                0                 0                  0

MODELVIEW
    1 073 741 824     1 073 741 824       -1 073 741 824         1 071 119 123
          0                0               1 073 741 824         1 072 511 075
   -1 073 741 824     1 072 523 682              0              -1 077 637 615
   -2 147 483 648    -1 069 923 613              0              -1 071 413 844

使用gluPerspective和生成矩阵gluLookAt。视口显然是正确的,但矩阵是错误的,不仅因为它们的值对我来说似乎不太正常,还因为值在矩阵元素之间的分布(参见 [1,2] 元素投影矩阵应该为零,但它不是,而 [3,3] 元素为零,它不应该)。

这些奇怪的值指向glGet()函数调用中的一些问题,但我想不通。我已经检查过我没有在andglGet()之间打电话。实际上,我在正确绘制一些点之后和使用相同的 ModelView 和 Projection 矩阵正确绘制一些球体之前调用。我的代码有一个更大的片段(调用序列是):glBegin()glEnd()glGet()main->CheckForPlanetPosition->Planet::GetScreenLocation

typedef struct position {
  int x,y,z;
};

int main()
{
    glEnable(GL_DEPTH_TEST);
    glViewport(0,0,1366,768);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60,16.0f/9.0f,1,1000);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(Camera.x,Camera.y,Camera.z,Camera.cx,Camera.cy,Camera.cz,0,1,0);

    //calls to glEnable

    //some drawing
    glBegin(GL_LINES);
    for(float i=1;i<15;i++)
    {
        glColor4f(0,120.0f/255.0f,210.0f/255.0f,1.0f);

        glVertex3f(0,0.5f,i*100.0f/15.0f);
        glVertex3f(100,0.5f,i*100.0f/15.0f);
        glVertex3f(i*100.0f/15.0f,0.5f,0);
        glVertex3f(i*100.0f/15.0f,0,100);
    }
    glEnd();

    CheckForPlanetsLocation();
    //other stuff...
   return 0;
  }

bool CheckForPlanetsLocation()
{
    position pos;
    pos=SomePlanet.GetScreenLocation();
    //check that the mouse is over the returned region...
}

position Planet::GetScreenLocation()
{
        GLint view[4]={0};
        GLdouble proj[16]={0};
        GLdouble model[16]={0};
        GLdouble x,y,z;

        glGetDoublev(GL_PROJECTION_MATRIX,proj);
        glGetDoublev(GL_MODELVIEW_MATRIX,model);
        glGetIntegerv(GL_VIEWPORT,view);

        gluProject(pos.x,pos.y,pos.z,model,proj,view,&x,&y,&z);
        position res;

        res.x=(int)x;
        res.y=(int)y;
        res.z=(int)z;
        return res;
}

希望你这次能帮到我!提前感谢您的回答:)

4

1 回答 1

2

问题是当你传递gluProject一个数组时需要一个类型的数组。当它进行迭代时,它将使用 a 的大小进行迭代,这是 float 大小的两倍!因此,它会跳过一些元素并为其他元素提供垃圾。用 double 交换那些浮点数组并使用来获取您想要的值。doublefloatdoubleglGetDoublev

此外,您的gluPerspective代码中有一个小错误 - 16/9在传递给函数之前将整数截断为 1。这不是您的投影问题的原因,但最好记住整数截断会破坏您的浮点计算。

最后,我要成为那个人,并说在这个时代学习 OldenGL(我称之为)弊大于利。现代 OpenGL 有很多很棒的在线教程,例如:

开放式GL

学习OpenGL

任何提及 OpenGL 2 及更高版本的内容都是您想要的。

于 2015-06-26T20:36:19.623 回答