OpenGL Math - Проецирование Экранное пространство для мировых космических коордов

Время для немного математики в конце дня..

Мне нужно проецировать 4 очка размера окна:

<0,0> <1024,768>

В мировые космические координаты, таким образом, он образует четырехгранную форму, которая позже будет использоваться для отбраковки рельефа - без GluUnproject

Только для теста я использую координаты мыши - и пытаюсь проецировать их на мировые координаты

Ответ 1

ПОСТАНОВИЛИ

Здесь, как это сделать, шаг за шагом.

0) Получить координаты мыши в клиентской области

1) Получите матрицу проекции и матрицу просмотра, если не требуется матрица модели.

2) Умножение проекции * Просмотр

3) Обратные результаты умножения

4) Построить вектор 4, состоящий из

x= mouseposition.x в диапазоне окна x - преобразовать значения между -1 и 1

y= mouseposition.y пределах диапазона окна y - преобразовать значения между -1 и 1 - запомнить инвертировать mouseposition.y при необходимости

z= the depth value (это можно получить с помощью glReadPixel) - вы можете вручную перейти от -1 к 1 (zNear, zFar)

w= 1.0

5) Умножьте вектор на инвертированную матрицу, созданную до

6) Разделите вектор результата по этому компоненту w после умножения матрицы (разделение перспективы)

        POINT mousePos;
        GetCursorPos(&mousePos);
        ScreenToClient( this->GetWindowHWND(), &mousePos );         

        CMatrix4x4 matProjection = m_pCamera->getViewMatrix() *  m_pCamera->getProjectionMatrix() ;

        CMatrix4x4 matInverse =  matProjection.inverse();


        float in[4];
        float winZ = 1.0;


        in[0]=(2.0f*((float)(mousePos.x-0)/(this->GetResolution().x-0)))-1.0f,
        in[1]=1.0f-(2.0f*((float)(mousePos.y-0)/(this->GetResolution().y-0)));
        in[2]=2.0* winZ -1.0;
        in[3]=1.0;          

        CVector4 vIn = CVector4(in[0],in[1],in[2],in[3]);
        pos = vIn * matInverse;

        pos.w = 1.0 / pos.w;

        pos.x *= pos.w;
        pos.y *= pos.w;
        pos.z *= pos.w;



        sprintf(strTitle,"%f %f %f / %f,%f,%f ",m_pCamera->m_vPosition.x,m_pCamera->m_vPosition.y,m_pCamera->m_vPosition.z,pos.x,pos.y,pos.z);

        SetWindowText(this->GetWindowHWND(),strTitle);

Ответ 2

Умножьте все свои матрицы. Затем инвертируйте результат. Точка после проекции всегда находится в -1, 1. Таким образом, четыре угловых экрана - -1, -1; -1, 1; 1, -1; 1,1. Но вам все равно нужно выбрать значение z. Если вы находитесь в OpenGL, z находится между -1 и 1. Для directx диапазон от 0 до 1. Наконец возьмите свои точки и преобразуйте их с помощью матрицы

Ответ 3

Если у вас есть доступ к библиотекам glu, используйте gluUnProject (winX, winY, winZ, model, projection, viewport и objX, & objY, & objZ);

winX и winY будут углами вашего экрана в пикселях. winZ - это число в [0,1], которое укажет, где между zNear и zFar (плоскостями отсечения) точки должны падать. objX-Z будет содержать результаты. Средние переменные являются соответствующими матрицами. При необходимости они могут быть запрошены.