2014-12-18 3 views
0

У меня есть следующая проблема: я рисую 2D-сцену, используя opengl, который содержит набор точек. Каждая точка указана, так как это XY-координаты. Я бы хотел использовать символ маркера - нечто вроде треугольника, креста или квадрата для визуализации точек. Проблема в том, что размер маркера должен быть постоянным на экране при масштабировании сцены - что-то вроде использования GL_POINTS. Поэтому каждый раз, когда я меняю масштаб, мне приходится пересчитывать координаты своих маркеров, и это не удобно - я бы хотел сделать это один раз, когда получаю новую позицию точки рендеринга. Есть ли проблемы?OpenGL 2D-маркерный символ

ответ

1

Простейший подход, вероятно, состоит в том, что у вас есть текстуры с вашими символами, а затем рисуйте их с помощью точечных спрайтов. Если вам нужна помощь с этим подходом, мой ответ здесь объясняется, как использовать точечные спрайты:

Render large circular points in modern OpenGL

Другой подход, который приходит на ум, что вы применить масштабирование геометрии в вершинном шейдере после всех были применены другие преобразования, включая проекцию.

Самого лучшего, что приходит на ум сразу, что вы передаете два атрибута для каждой вершины в вершинном шейдере:

  • центр маркеров, который имеет то же значение для всех вершин одного маркеров.
  • Относительное смещение от центра маркера.

Затем в вершинном шейдере, то применяются все обычные преобразования, вплоть до и включая преобразование проекции, к центру только. Затем вы добавляете относительное смещение.

набрасывать вершинный шейдер, он может выглядеть следующим образом:

in vec3 centerPos; 
in vec2 relativePos; 
uniform mat4 ModelViewProj; 
... 

void main() { 
    ... 
    vec4 projCenterPos = ModelViewProj * vec4(centerPos, 1.0); 
    gl_Position = vec4(
     projCenterPos.xy + projCenterPos.w * relativePos, 
     projCenterPos.zw); 
} 

Поскольку относительное смещение применяется после того, как проекции, вы должны принять во внимание, что мы теперь имеем однородные координаты, где x, y , а z будет разделен на w как часть обработки фиксированной функции после вершинного шейдера. Чтобы сделать размер постоянным после этого перспективного деления, приведенный выше код умножает смещение на w.

С relativePos по существу применяется в НДЦ (координаты нормализованных устройств), где диапазон в х- и у-направлениях равен [-1,0, 1,0], значения должны быть довольно малы. Например, смещение 0,02 соответствует 1% от размера окна.

Если вы хотите, чтобы размер был более гибким, вы могли бы передать другой масштабный коэффициент для управления размером спрайта и умножить relativePos на коэффициент выше. Затем вы можете сохранить относительные позиции, например. в пределах диапазона [-1,0, 1,0], а затем соответствующим образом масштабировать их:

... 
uniform float spriteSize; 
... 

    gl_Position = vec4(
     projCenterPos.xy + spriteSize * projCenterPos.w * relativePos, 
     projCenterPos.zw); 
+0

Большое вам спасибо за ваш ответ! –