Есть пара способов, которыми я мог бы подумать сделать это.
Возможность 1
Пользователь щелкает в окне окна, поэтому теперь у вас есть координаты окна щелчка мыши (x, y). Теперь добавьте один пиксель в направлении X (x + 1 / width, y) и один пиксель в направлении y (x, y + 1 / height), где width и height - это размеры в пикселях дисплея. используйте gluUnProject для всех трех этих векторов, тогда у вас есть три точки в пространстве объектов {A, B, C}. Если у вас есть три точки в пространстве объектов, обычный расчет относительно прост:
A = ObjectCoordinates(x+1/width, y)
B = ObjectCoordinates(x, y)
C = ObjectCoordinates(x, y+1/height)
BA = (A-B)/|A-B|
BC = (C-B)/|C-B|
N = BA cross BC
где | X | это величина вектора X
и нормаль N
Это может быть не быстро, и у него будут проблемы, когда A, B и C не все приземляются в одном и том же треугольнике (это может произойти, если вы нажимаете на объект, который действительно далеко). Но он должен получить хороший приблизительный результат.
Возможность 2
Теперь об этой следующей возможности я не очень уверен, но здесь идет речь. Создайте фрагментный шейдер и вершинный шейдер. Вам нужно будет создать двухпроходную систему рендеринга. Первый проход использует эти недавно созданные шейдеры, второй проход фактически отображает вашу сцену. Это может значительно замедлить выполнение программы, потому что вам нужно сделать два полных рендера сцены за кадр.
При первом проходе ваш вершинный шейдер пройдет вершину, нормальную к вашему фрагментному шейдеру. Затем вы назначаете цвет фрагмента (r, g, b) нормальным координатам, переданным из вашего вершинного шейдера (x, y, z). Затем ваш первый проход будет визуализироваться с использованием этих шейдеров. Ваш второй проход будет визуализироваться в буфер кадров. Когда пользователь щелкает, вы получаете набор координат пространства окна, которые вы конвертируете в (u, v) координаты текстуры для выборки из текстуры, созданной при первом проходе рендеринга.
Опять же, это решение будет значительно медленнее, но, скорее всего, оно даст вам более точные данные в зависимости от размера текстуры, которую вы используете.
Здесь - немного устаревшая, но бесплатная книга по GLSL - языку шейдеров OpenGL, в котором описывается, как вы собираетесь собрать вместе некоторые из этих шейдеров.
Здесь - учебник по загрузке и компиляции шейдеров.
Здесь - псевдокод для вычисления нормали.
Ура,
Ned