0

所以我有一个绘制几个球体的小程序,然后我尝试右键单击它们。右键单击时,它会在我单击鼠标时在近平面和远平面之间绘制一条线。然而,它给出了奇怪的结果,比如这条线很长。然而,这条线的方向是正确的,只是这条线可能沿着 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);
4

2 回答 2

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,如果它们还不是齐次坐标。

如果你不转换对象空间和世界空间之间的坐标,那么你会得到你正在经历的行为,而且在错误的阶段也很容易做到这一点,所以计划好所需的步骤,你应该没问题:)

希望这可以帮助。

于 2013-10-25T12:56:22.443 回答
0

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

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

于 2013-10-28T05:16:22.197 回答