Размер прямоугольника OpenGL произвольно изменяется на один пиксель при перемещении

Я нарисовал небольшой контур 2D-прямоугольника в OpenGL с помощью GL_LINE_LOOP — очень стандартная вещь, представленная в многочисленных учебниках. Прямоугольник не вращается в пространстве, его ось выровнена с экраном. У меня есть вызов glTranslatef(x, y), чтобы мой прямоугольник перемещался по экрану. Координаты вершин представляют собой постоянную долю ширины и высоты экрана.

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

Неважно, включено сглаживание или нет, хотя, если сглаживание включено, линия временно кажется двойной (или толще).

Мне было интересно, является ли это стандартным в OpenGL, и есть ли команда, которую мне не хватает, чтобы избежать мини-изменения размера при анимации прямоугольника.


person CodeTrek    schedule 25.09.2015    source источник


Ответы (1)


Судя по описанию, это, скорее всего, ваша проблема:

Координаты вершин представляют собой постоянную долю ширины и высоты экрана.

Теоретически эти координаты находятся точно на границе между двумя пикселями. Из-за неточности с плавающей запятой вершина может оказаться внутри любого из двух соседних пикселей.

Чтобы упростить объяснение, предположим, что ваше окно имеет ширину 20 пикселей, и вы используете NDC (нормализованные координаты устройства) для указания своих вершин. Таким образом, диапазон координат равен [-1.0, 1.0]. Разделение диапазона 2,0 единиц координат на 20 пикселей означает, что каждый пиксель имеет ширину 0,1 единицы. Тогда диапазоны координат, покрываемые каждым пикселем, будут следующими:

[-1.0, -0.9], [-0.9, -0.8], [-0.8, -0.7], ... , [0.8, 0.9], [0.9, 1.0]

Поэтому, если вы используете координаты, которые являются долями количества пикселей, например -0,8, эта координата находится на границе между двумя пикселями.

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

-0.95, -0.85, -0.75, ... , 0.85, 0.95

В общем, если ваш диапазон координат составляет от xMin до xMax, и у вас есть n пикселей в этом диапазоне, центральная координата пикселя k будет:

xMin + ((k + 0.5) / n) * (xMax - xMin)
person Reto Koradi    schedule 25.09.2015
comment
Спасибо. Я думал решить это аналогичным образом, но я надеялся, что в OpenGL будет что-то встроенное, чтобы этого не произошло. - person CodeTrek; 25.09.2015