Нажатие на Quad и получение координат экрана в opengl

Скажем, я делаю четырехугольник так:

float botBaseY = -0.5;
glBegin(GL_QUADS); // Box
    glVertex2f(-.05, botBaseY + -.05);
    glVertex2f(-.05, botBaseY + .05);
    glVertex2f(.05, botBaseY + .05);
    glVertex2f(.05, botBaseY + -.05);
glEnd();

Хорошо, хорошо, теперь скажите, что я хочу определить, нажал ли пользователь внутри этого четырехугольника. Хорошо, когда вы нажимаете, вы получаете координаты экрана, поэтому, если ваше главное окно имеет размер 600x600 пикселей, то ваш щелчок приведет к значению x и y меньше 600. Но я сравниваю щелчок по скажем (375 400) с квадратом, который был создан с использованием значений от -1,0 до 1,0, чтобы определить 4 вершины.

Как я могу определить, нажал ли пользователь внутри четырехугольника?

3 ответа

Решение

Я никогда не получал полезный ответ здесь, но я все же выяснил это на следующий день. Моя коробка рисовалась с использованием координат от -1 до 1. Но у моего клика были большие экранные координаты, например 200 300. Мне нужно было знать, как преобразовать -1 в 1 в экранные координаты или как просто нарисовать совместимые координаты.

glMatrixMode(GL_PROJECTION);
gluOrtho2D(0, 400, 0, 400);
glBegin(GL_QUADS); // Box
    glVertex2f(xOffset + topBaseX + -15, topBaseY + -15);// bottom left vert
    glVertex2f(xOffset + topBaseX + -15, topBaseY + 15); // top left vert
    glVertex2f(xOffset + topBaseX + 15, topBaseY + 15);// top right vert
    glVertex2f(xOffset + topBaseX + 15, topBaseY + -15);// bottom right vert
glEnd();
glLoadIdentity();

Это было все, что я должен был сделать, чтобы нарисовать свою коробку примерно в 200 300, и тогда я мог просто проверять границы своей коробки при каждом клике.

В настоящее время я вижу 2 способа сделать это.

  1. если ваш "интерфейс" полностью 2D и напрямую отображается на экране - вы можете просто использовать экранные координаты для рисования. Просто установите правильную орфографическую матрицу, и ваши координаты клика будут такими же, как координаты 2D-элементов - простое сравнение диапазона (x

  2. если первый вариант не соответствует вашей ситуации - вам нужно отобразить 2D-координаты, чтобы увидеть пространство и использовать полученную точку в качестве направления луча. Затем проследите пересечение этого луча с плоскостью элемента, которую вы хотите щелкнуть. Взгляните на http://www.toymaker.info/Games/html/picking.html - не важно, что это для d3d, математика всегда одинакова). Затем, когда вы возьмете полученную точку щелчка на плоскости, которая вас интересует, - это опять-таки просто сравнение дальности (хотя будет немного сложнее, если ваша плоскость не параллельна экрану - но я не думаю, что она все еще тот же вопрос).

Самый простой и точный (но не обязательно самый эффективный) способ:

Снова визуализируйте сцену (в закадровый буфер) с целевым объектом белым, а все остальное - черным. Если пиксель под курсором белый, цель была нажата. Если вы хотите иметь возможность просматривать прозрачные материалы, просто пропустите рендеринг этих объектов.

Для эффективности вы можете сделать это с выключенным смешиванием и уникальным цветом (возможно, индексом) для каждого объекта. И используйте новые возможности OpenGL, чтобы заполнить плоскость выбора цвета во время обычного рендеринга, вместо того, чтобы делать дополнительный проход.

Другие вопросы по тегам