1

gluUnProjectを使用してマウス座標をワールド座標にしようとしていますが、機能していないようです。または、glUnProject関数の機能を誤解しているだけです。これが、使用しているコードです。マトリックスはすべて正常にチェックアウトされます。マウスのx座標の-300については、C ++ Win32ダイアログを使用しており、ScreenToClientからファンキーな結果が得られます。

        int appWidth  = CApplication::GetInstance()->GetWidth();
        int appHeight = CApplication::GetInstance()->GetHeight();
        float fAspect = (float)appWidth / (float)appHeight;

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(60.0f, fAspect, 0.1f, 100000.0f);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glTranslatef(m_vecCamera.x, -m_vecCamera.y, m_vecCamera.z);

        GLint viewport[4];
        GLdouble modelview[16];
        GLdouble projection[16];
        GLfloat winX, winY, winZ;
        GLdouble posX, posY, posZ;

        glEnable(GL_DEPTH);
        //Retrieve the Model/View, Projection, and Viewport Matrices
        glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
        glGetDoublev( GL_PROJECTION_MATRIX, projection );
        glGetIntegerv( GL_VIEWPORT, viewport );

        //Retrieve the Mouse X and the flipped Mouse Y
        winX = (float)pInput->msg.param1-300.0f;
        winY = (float)viewport[3]-(float)pInput->msg.param2;
        glReadPixels( int(winX), int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );

        gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);

ただし、これにより、画面の中心を基準にした座標が得られます。カメラを基準にしたものと想定しているので、独自の機能を実装してみました。

Vector2f MouseUnProject(int x, int y)
{

        GLint viewport[4];
        GLdouble modelview[16];
        GLdouble projection[16];
        GLfloat winX, winY, winZ;
        GLdouble posX, posY, posZ;

        glEnable(GL_DEPTH);
        //Retrieve the Model/View, Projection, and Viewport Matrices
        glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
        glGetDoublev( GL_PROJECTION_MATRIX, projection );
        glGetIntegerv( GL_VIEWPORT, viewport );

        //Retrieve the Mouse X and the flipped Mouse Y
        winX = (float)x;
        winY = (float)viewport[3]-y;
        glReadPixels( int(winX), int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );

        double projectionX, projectionY;
        double viewX, viewY;
        double worldX, worldY;

        //Convert from Screen Coords to Projection Coords
        projectionX = (double)winX / ((double)viewport[2]/2.0) - 1.0;
        projectionY = (double)winY / ((double)viewport[3]/2.0) + 1.0;

        //Convert from projection Coords to View Coords
        viewX = projectionX * modelview[14];
        viewY = projectionY * modelview[14];

        //Convert from View Coords to World Coords
        worldX = viewX + modelview[12];
        worldY = viewY - modelview[13];

        return Vector2f(worldX, worldY);

}

特定のマウントで動作しますが、カメラを動かすと、数値がすぐに少しずれ、投影からビュー座標への変換は「問題ないようです」、投影座標は間違いなく良好です。

私は自分の関数よりもglUnProjectを使用したいのですが、それを一生機能させることができず、見つけたすべてのgoogle検索が私の質問に答えていないようです。GLドキュメントが「オブジェクトスペース」とは正確に何を意味するのでしょうか。おそらくそれについての私の理解は間違っています。もしそうなら、正しいスペースで座標を取得するためにさらに何をしなければなりませんか?

4

1 に答える 1

0

1年前に投稿されましたが、とにかく.... gluPerspectiveを呼び出したため、画面に対する座標を取得しています。この呼び出しは、範囲 {-1, 1} で正規化された座標を生成する glfrustum を内部的に呼び出します。ただし、near/far 値を指定して glfrustum を直接呼び出した場合、その範囲で gluUnproject からの結果が得られます。

マップ エディターの座標に戻すには、gluUnproject から結果を取得し、手動で範囲変換してエディターの座標系に戻します (つまり、{-1,1} => {0, max})。

開始するには、(0,0)、(midX、midY)、(maxX、maxY) を入力して gluUnProject をテストする必要があります。gluUnProject の結果は (-1、-1、深さ)、(0、0、深さ) になります。および(1、1、深さ)。glFrustum を使用して射影行列を設定すると、上記の結果が近距離/遠距離の範囲で返されます。

于 2013-10-20T17:43:30.850 に答える