gluUnProject не работает

Я пытаюсь использовать gluUnProject, чтобы перевести координаты мыши в мировые координаты, однако, похоже, это не работает, или я просто неправильно понимаю функциональность функции glUnProject, вот код, с которым я работаю, мои матрицы все в порядке а что касается -300 по координате x мыши, я использую диалог 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 подразумевает под «объектным пространством», возможно, мое понимание этого неверно, и если да, то что мне дополнительно нужно сделать, чтобы получить мои координаты в правильном пространстве?


person user1294021    schedule 03.08.2012    source источник
comment
Вам нужна некоторая геометрия для преобразования (например, над чем находится ваша мышь? - нет смысла преобразовывать в мировые координаты, когда в вашем мире ничего нет). Вы рисуете геометрию, верно?   -  person imallett    schedule 04.08.2012
comment
Я хотел получить координаты мыши в камере Z (которая начинается с -100) относительно матрицы идентичности мира, документация GLU действительно расплывчата в отношении того, что делает эта функция, я установил матрицу проекции и сбросил модель/ просмотреть матрицу и применил к ней перевод камеры, у меня есть карта (текстурированные квадраты), которая начинается с (0,0,0) и простирается оттуда в одном направлении. У меня сложилось впечатление, что эта функция даст мне в основном положение моей мыши до применения преобразования вида, что я не вижу и как мне правильно использовать эту функцию?   -  person user1294021    schedule 04.08.2012
comment
Координаты мыши плюс глубина дают вам положение объекта после разделения перспективы (т. Е. Координата экрана: в такой-то позиции (x, y) и на определенной глубине экрана). Что делает gluUnProject, так это преобразует эту позицию обратно в позицию исходного объекта. Итак, если вы рисуете треугольник, и вершина треугольника попадает в пиксель (124,89) с глубиной 0,647, то gluUnProject сможет сообщить вам координаты этой вершины. Я не совсем уверен, в чем ваша проблема, но тогда я не совсем уверен, о чем вы спрашиваете.   -  person imallett    schedule 04.08.2012
comment
Проще говоря, у меня есть редактор карт, я хочу получить координаты моей мыши в трехмерном пространстве. Моя карта начинается с (0,0) и расширяется, скажем, на 1000 по осям X и Y, я хочу, чтобы мои полученные координаты скажем 0,0 в левом верхнем углу карты, и 1000, 1000 в правом нижнем углу, независимо от перевода камеры, то есть когда моя мышь наводит на них   -  person user1294021    schedule 05.08.2012
comment
Хорошо. Итак, вот как это будет работать: вы начинаете свой кадр. Вы рисуете свою карту. Вы пробуете глубину под мышью. Вы передаете положение мыши и глубину в gluUnProject вместе с текущими значениями матриц представления модели и проекции. В результате должно получиться желаемое положение. Я подозреваю, что ваша проблема заключалась в том, что вы сначала не визуализировали объект, поэтому значение глубины было неправильным. Вы должны проверить это с помощью оператора печати - он должен значительно измениться, когда вы наведете указатель мыши на свой объект.   -  person imallett    schedule 05.08.2012
comment
Хорошо, так что я на шаг ближе, я думаю, то, что вы сказали, сработало, я сделал функцию gluUnProject сразу после рисования, и она действительно работает, когда я рисую точку по заданным координатам, все проверяется, дайте мне еще один вопрос хотя координаты, которые мне показываются, кажутся неправильными, например, когда я рисую свою карту, это тождественная матрица, затем перевод камеры, затем я рисую свои квадроциклы, первый из которых имеет размер всего 1000x1000. Я знаю, что координаты правильные, так как точка рисует там, где находится мышь, но почему они отличаются от того, что я передаю в glBegin   -  person user1294021    schedule 05.08.2012
comment
координаты кстати очень большие, при том что я надеялся увидеть 0,0 получилось -15000, -9500, -97500. И еще более странно на другой стороне карты, я знаю, что это «правильные» координаты, иначе моя точка не будет отображаться в нужном месте, однако в чем разница между координатами, которые у меня есть, и координатами, которые я хочу? И есть ли решение получить координаты, которые я хочу?   -  person user1294021    schedule 05.08.2012


Ответы (1)


был опубликован год назад, но в любом случае .... так что вы получаете координаты относительно экрана, потому что вы сделали вызов gluPerspective. этот вызов внутренне вызывает glfrustum, который генерирует нормализованные координаты в диапазоне {-1, 1}. Однако, если бы вы вызвали glfrustum напрямую с вашими значениями close/far, вы бы получили результат от gluUnproject в этом диапазоне.

Чтобы вернуться к координатам вашего редактора карт, просто возьмите результат из gluUnproject и вручную преобразуйте диапазон обратно в систему координат вашего редактора, т.е. {-1,1} => {0, max}

Для начала вы должны протестировать gluUnProject, введя (0,0), (midX, midY), (maxX, maxY), и результат от gluUnProject должен быть (-1, -1, глубина), (0, 0, глубина) и (1, 1, глубина). Если вы настроите матрицу проекции с помощью glFrustum, то приведенный выше результат будет возвращен в ближнем/дальнем диапазоне.

person Mr Bat Lee    schedule 20.10.2013