获取模型坐标,在OpenGl中返回错误的值

时间:2013-10-25 11:11:07

标签: c++ opengl

所以我有一个小程序可以绘制几个领域,然后我尝试右键单击它们。在右键单击时,它会在我点击时在鼠标下方的近和远平面之间画一条线。然而,它给出了奇怪的结果,例如线路已经走了很长一段路。然而,线的方向是正确的,只是沿着X可能左边大约是10,或者沿着Y可以是5到右边(这些是随机的例子)。

这是我的代码:

放置相机

gluLookAt(mouse.getScrollY(), 0.0f,  0.0f,
          0.0f, 0.0f,  0.0f,
          0.0f, 0.0f,  1.0f);

glRotated(mouse.getAngleV(), 0.0f, -1.0f, 0.0f);
glRotated(mouse.getAngleH(), 0.0f, 0.0f, -1.0f);

mouse.getScrollY只是一个基于相机从原点向后滚动多远的值。

获取坐标

void Mouse::GetGLPos(int x, int y)
{
//init vars:
    GLint viewport[4];
    GLdouble modelview[16];
    GLdouble projection[16];
    GLfloat winX, winY;
    GLdouble posX, posY, posZ;

    GLdouble FposX, FposY, FposZ;
//get gl specs

    glGetDoublev( GL_MODELVIEW_MATRIX, modelview ); //get Modelmatrix
    glGetDoublev( GL_PROJECTION_MATRIX, projection );   //get projection matrix
    glGetIntegerv( GL_VIEWPORT, viewport );     //get viewport values
//calculate the gl mouseposition

    winX = (float)x;
    winY = (float)viewport[3] - (float)y;

    std::cout << "X "<< winX << " Y " << winY << endl;


    gluUnProject( winX, winY, 0.0, modelview, projection, viewport, &posX, &posY, &posZ);
    gluUnProject( winX, winY, 1.0, modelview, projection, viewport, &FposX, &FposY, &FposZ);


    std::cout << "Near positions:" << posX << " | " << posY << " | " << posZ << endl;
    std::cout << " Far positions:" << FposX << " | " << FposY << " | " << FposZ << endl << endl;

    for (int i = 0; i <= 15; i++)
    {
        cout << modelview[i] << endl;
    }

    if (counter == 5)
    {
        counter = 0;
    }
    LinestoreNear[counter + 1] = Vec3(posX, posY, posZ);
    LinestoreFar[counter + 1] = Vec3(FposX, FposY, FposZ);

    counter ++;
    mouseOgl[0] = posX;
    mouseOgl[1] = posY;
    mouseOgl[2] = posZ;
}

传递给它的x和y只是鼠标在屏幕上的x和y坐标。 (例如(328,657))

最后,为了以防万一,这里是绘制线

glDisable(GL_LIGHTING);
for (int i = 0; i <= 4 - 1 ; i++)
{
    glColor3f(1.0f, 1.0f, 1.0f);
    glBegin(GL_LINES);
    glVertex3f(mouse.LinestoreNear[i].a, mouse.LinestoreNear[i].b, mouse.LinestoreNear[i].c);
    glVertex3f(mouse.LinestoreFar[i].a, mouse.LinestoreFar[i].b, mouse.LinestoreFar[i].c);
    glEnd();
}
glEnable(GL_LIGHTING);

2 个答案:

答案 0 :(得分:0)

以下是您需要使用的过程的简要概述

要获得正确的世界坐标,您需要为场景中的每个对象提供4x4模型矩阵。模型矩阵包含转换操纵模型坐标到世界坐标/从世界坐标转换的所有变换。

即每次调用glTranslate时,都必须按如下方式转换模型矩阵:

T  = [ 1 0 0 x ]
     [ 0 1 0 y ]
     [ 0 0 1 z ]
     [ 0 0 0 1 ]
M' = M * T

然后,您可以使用变换后的模型矩阵来获取世界空间坐标 然而,首先将坐标均匀化(或检查它们已经是),即。如果它们不是同质坐标,则设置w = 1。

如果你没有转换对象空间和世界空间之间的坐标,那么你将得到你正在经历的行为,并且在错误的阶段也很容易做到,所以计划出所需的步骤你应该是细:)

希望这有帮助。

答案 1 :(得分:0)

终于有时间验证你的结果了。它完全按照预期工作。

使用LookAt指定(GLU将为您计算这些矩阵)摄像机位置和旋转矩阵(间接地,通过“向上”和“视点”向量,但仍然会导致这些变换)。就在您指定两个额外的旋转矩阵之后 - 这意味着,您将围绕零点(已经移位LookAt)旋转世界。对于你来说,这种旋转看起来像是相机在空间的某个点周围旋转,保持恒定的距离。保持位置的线条,通过透视变换引入的一些失真(如果有的话),被远剪裁平面剪切(这看起来在旋转期间线条变得越来越短)。