У меня есть 2 вопроса. Один конкретный вопрос о том, почему мой код работает не так, как задумано, а другой вопрос о дизайне.
1 (Конкретный вопрос): я пытаюсь отобразить экранные координаты на мировые координаты в 2D-движке на основе плиток (использует ось x / y, z = 0). Я использовал учебный порт Nehe о том, как этого добиться, но результаты, которые я получаю, не такие, как ожидалось.
У меня есть класс MouseController. Всякий раз, когда вызывается событие мыши (через MouseListener свинга), я передаю MouseEvent в свой MouseController.
В функции рисования моего GLCanvas я вызываю функцию MouseController.processClick (GL), чтобы передать текущий контекст gl в функцию processClick и получить представление модели, матрицы проекции и область просмотра.
Когда я нажимаю на блок, отображаемый на экране, мировые координаты, которые мне возвращаются, почти не имеют смысла. Во-первых, я бы ожидал, что значение z будет равно 0, но его 9 (то есть, насколько высоко установлена моя камера), а мои значения x и y всегда действительно близки к 0 (иногда скачок до 1-9 с очень легкие движения, затем обратно к числу, очень близкому к 0).
У кого-нибудь есть идеи, почему это может иметь место? Функция processClick находится ниже:
public void processClick(GL gl) {
int x = e.getX();
int y = e.getY();
if(e.getButton() == MouseEvent.BUTTON1) {
gl.glGetIntegerv(GL.GL_VIEWPORT, viewPort, 0);
gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX, mvMatrix, 0);
gl.glGetDoublev(GL.GL_PROJECTION_MATRIX, prMatrix, 0);
int realy = viewPort[3] - y;
glu.gluUnProject((double)x, (double)realy, 0, mvMatrix, 0, prMatrix, 0, viewPort, 0, wCoord, 0);
System.out.println(x + " " + y);
System.out.println(x + " " + realy);
System.out.println(wCoord[0] + " " + wCoord[1] + " " + wCoord[2]);
}
e = null;
}
Пример вывода, который я получаю из вышеуказанной функции, когда нажимаю на экран, где я рендерил квадрат с мировыми координатами (4,5,0):
878 56
878 636
0.0445182388817236 0.055475957454737095 8.900000001489369
спасибо!
РЕДАКТИРОВАТЬ: Чтение в буфере глубины с использованием glReadPixels и использование его в качестве z (который возвращает 1) дает мне результаты, которые вроде бы правильные, но слишком большие в 20 раз.
EDIT2: Если я установлю плоскость отсечения на дальность на то же значение, что и высота камеры, она, похоже, будет работать (но это не совсем подходит).
2 (Вопрос о дизайне): мне кажется, что нет смысла обрабатывать щелчки в функции рисования холста OpenGL. Я, кажется, требую, чтобы GL из этой функции мог извлекать матрицы, необходимые для запуска gluUnProject. Как вы, ребята, спроектируете это? В идеале мне кажется, что я должен иметь возможность этого прогона полностью отделить от функции рисования. Сохраните ссылку на объект gl в моем MouseController и обработайте щелчок, когда MouseListener обнаружит его.
Вводная информация о том, как вы, ребята, справитесь, будет очень признательна!