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

C++ 在OpenGl中获取返回错误值的模型坐标,c++,opengl,C++,Opengl,我有一个小程序画了几个球体,然后我试着右键点击它们。单击鼠标右键后,它在近平面和远平面之间绘制一条线,单击鼠标时在鼠标下方。然而,它会产生奇怪的结果,比如说,这条线已经走了相当长的一段路。这条线的方向是右的,但是,这条线可能是沿着X向左10,或者沿着Y向右5(这些是随机的例子) 这是我的密码: 定位摄像机 gluLookAt(mouse.getScrollY(), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1

我有一个小程序画了几个球体,然后我试着右键点击它们。单击鼠标右键后,它在近平面和远平面之间绘制一条线,单击鼠标时在鼠标下方。然而,它会产生奇怪的结果,比如说,这条线已经走了相当长的一段路。这条线的方向是右的,但是,这条线可能是沿着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;
}
void鼠标::GetGLPos(int x,int y)
{
//初始化变量:
闪烁视口[4];
GLdouble modelview[16];
gl双投影[16];
GLfloat winX,winY;
GLdouble-posX,posY,posZ;
GLdouble-FposX,FposY,FposZ;
//获取gl规格
glGetDoublev(GL_MODELVIEW_MATRIX,MODELVIEW);//获取Modelmatrix
glGetDoublev(GL_投影_矩阵,投影);//获取投影矩阵
glGetIntegerv(GL_视口,视口);//获取视口值
//计算gl鼠标位置
winX=(float)x;
winY=(浮动)视口[3]-(浮动)y;

std::cout这里是您需要使用的过程的一个非常简短的概述

要获得正确的世界坐标,场景中的每个对象都需要一个4x4模型矩阵。模型矩阵包含将模型坐标转换为/转换为世界坐标的所有变换

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

T  = [ 1 0 0 x ]
     [ 0 1 0 y ]
     [ 0 0 1 z ]
     [ 0 0 0 1 ]
M' = M * T
然后,可以使用变换后的模型矩阵获取世界空间坐标 但是,首先对坐标进行均匀化(或检查它们是否已经均匀化),即,如果它们还不是均匀坐标,只需设置w=1即可

如果您不在对象空间和世界空间之间转换坐标,那么您将获得您正在经历的行为,并且很容易在错误的阶段进行转换,因此请规划所需的步骤,您应该可以:)


希望这能有所帮助。

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


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

从眼睛的视角到远平面的直线是一个点。但当我旋转相机时,直线位于错误的位置。因此,近平面的XYZ与远平面的XYZ不同,我在它们之间画了一条线。然后旋转相机,查看直线是否到达我单击的位置,以便单击,然后旋转相机并查看您r线?那没关系。请问[counter+1]附近的
linestore怎么了
,不应该只是
计数器
,因为您在这之后就增加了它吗?当您调用此函数时,您当前的modelview矩阵是什么?只是查看还是它也有一些建模组件?行存储不是问题,我已经尝试过了。它根据camara查看它的位置而变化。我认为模式我想Glulookat正在更新l视图矩阵,但我不是100%确定。通过进一步探索,如果其中一个XYZ 0记不住gluUnProject后面的数学(并且现在没有时间检查),则该行大致位于正确的位置,但正如我所记得的,你们在最终的对象空间中得到向量。后来你们像在世界空间中一样使用它,但它不是。你们需要得到逆视图矩阵,并用这个矩阵乘以得到的线位置。
T  = [ 1 0 0 x ]
     [ 0 1 0 y ]
     [ 0 0 1 z ]
     [ 0 0 0 1 ]
M' = M * T