ОБРАТНЫЕ ПРЕОБРАЗОВАНИЯ ОКОННЫХ КООРДИНАТ В ОБЪЕКТНЫЕ
Часто требуется пользователю, используя мышь или другой указатель, выбрать точку в трехмерном пространстве, оперируя лишь ее проекцией на экране. Решая данную задачу, необходимо вспомнить, что оконные координаты объекта получаются из его мировых путем трех матричных преобразований: модельно-видовых, проекционных и преобразований к области вывода. И для определения мировых координат точки объекта по его оконным координатам требуется проделать обратные вышеприведенные преобразования. Но тут возникает другая проблема, множество точек из мировых координат, расположенных вдоль луча-проектора, дадут одну и ту же проекцию на экране. Для разрешения этой неоднозначности в OpenGL обратные преобразования решены командами gluUnProject() при диапазоне глубин в вашем приложении [0, 1], либо gluUnProject4(), если диапазон глубин отличается от [0, 1]. Рассмотрим параметры и функциональные возможности этих команд:
int gluUnProject (GLdouble winx, GLdouble winy, GLdouble winz, const GLdouble modelMatrix 16],const GLdouble projMatrix[16], const GLint viewport^],
GLdouble *objx, GLdouble *objy, GLdouble *objz)',
Данная команда преобразует заданные оконные координаты (winx, winy, winz) в объектные координаты (objx, objy, objz), используя преобра зования, заданные модельно-видовой матрицей (modelMatrix), проекционной матрицей (projMatrix) и портом просмотра (viewport). Если функция выполнилась удачно, то она возвращает значение GL_TRUE, в противном случае GL_FALSE.
Для получения однозначного результата от обратного преобразования команда gluUnProject() требует в качестве одного из своих параметров значение глубины в оконных координатах (winz). Если winz = 0.0, то вызов gluUnProjectQ вернет координаты точки (objx, objy и objz), расположенной на ближней плоскости отсечения объема видимости, а при winz = 1.0 будет вычислена точка на дальней плоскости отсечения.
Изъятие текущих значений матриц преобразований осуществляется командой:
void glGetDoublev ( GLenum рпате, GLdouble *params)
Параметр рпате определяет вид матрицы (см. документацию): модельно-видовой - GL_MODELVIEW_MATRIX;
проецирования - GL_PROJECTION_MATRIX. Параметр params указывает на массив размещения.
Значения параметров окна можно выбрать командой:
void glGetlntegerv (GLenum рпате, GLdouble *params)
Назначение параметров такое же, как и в команде glGetDoublev. Значение параметра рпате для окна должно быть GL_VIEWPORT.
Рассмотрим фрагмент программы, где по экранным координатам точки (х и у), например взятых от мыши, вычисляем значение координат точки объекта, обеспечивших эту проекцию. В качестве winz возьмем значение 0.0.
GLint viewport[4]; //для окна
GLdouble mv_matrix[16]; И для модельно-видовой матрицы
GLdouble proj_matrix[16]; // для матрицы прецирования
GLdouble obx,oby,obz; И Возвращаемые объектные х, у, z координаты GLint х,у;
// Обрабатываем событие от "мышки" (формируем значение хи у)
glGet!ntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX,mv_matrix);
glGetDoublev(GL_PROJECTION_MATRIX,proj_matrix); gluUnProject(x,у,0.0,mv_matrix,proj_matrix,viewport,&ox,&oy,&oz);
printf("Объектные координаты при z=0 (%f,%f,%f) ",ox,oy,oz);
Подобные ситуации часто возникают при выборе объектов на экране.