Конечные точки OpenGL GL_LINES не присоединяются - PullRequest
12 голосов
/ 26 декабря 2010

alt text У меня проблемы с блоком GL_LINES ... линии в примере ниже не соединяются на концах (хотя иногда он случайным образом решает соединить угол или два). Вместо этого конечные точки находятся в пределах 1 пикселя друг от друга (оставляя угол, который не является полностью квадратным; если это имеет смысл). Это простой блок для рисования сплошного 1-пиксельного прямоугольника.

 glBegin(GL_LINES);

  glColor3b(cr, cg, cb);

  glVertex3i(pRect->left, pRect->top, 0);
  glVertex3i(pRect->right, pRect->top, 0);

  glVertex3i(pRect->right, pRect->top, 0);
  glVertex3i(pRect->right, pRect->bottom, 0);

  glVertex3i(pRect->right, pRect->bottom, 0);
  glVertex3i(pRect->left, pRect->bottom, 0);

  glVertex3i(pRect->left, pRect->bottom, 0);
  glVertex3i(pRect->left, pRect->top, 0);

 glEnd();

Пример ниже, кажется, исправляет проблему, давая мне острые, квадратные углы; но я не могу принять это, потому что я не знаю, почему это так ...

 glBegin(GL_LINES);

  glColor3b(cr, cg, cb);

  glVertex3i(pRect->left, pRect->top, 0);
  glVertex3i(pRect->right + 1, pRect->top, 0);

  glVertex3i(pRect->right, pRect->top, 0);
  glVertex3i(pRect->right, pRect->bottom + 1, 0);

  glVertex3i(pRect->right, pRect->bottom, 0);
  glVertex3i(pRect->left - 1, pRect->bottom, 0);

  glVertex3i(pRect->left, pRect->bottom, 0);
  glVertex3i(pRect->left, pRect->top - 1, 0);

 glEnd();

Любые программисты OpenGL, которые могут помочь, я был бы признателен:)

Изображение представляет собой увеличенный снимок экрана. Как видите, верхний левый угол не подключен. Верхний правый угол есть. Не видны нижний левый и правый, которые не связаны.

В окне просмотра установлено значение от 1 до 1 пикселя на координату.

glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, __nRendererWidth, __nRendererHeight, 0, -1, 100);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glEnable (GL_TEXTURE_2D);

Ответы [ 4 ]

13 голосов
/ 26 декабря 2010

С вопрос 14.090 FAQ по OpenGL :

14.090 Как получить точную пикселизацию линий?

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

Возможно, вы захотите прочитать спецификацию OpenGL и ознакомиться с правилом выхода из бриллианта. Знание этого правила даст вам лучший шанс получить точную пикселизацию. Вкратце, правило выхода алмаза указывает, что ромбовидная область существует в каждом пикселе. Пиксель растеризуется линией, только если математическое определение этой линии выходит за ромб, вписанный в этот пиксель.

Затем из раздела 3.5 спецификации основного профиля OpenGL :

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

  1. Координаты фрагмента, созданного алгоритмом, не могут отклоняться более чем на одну единицу в координатах окна x или y от соответствующего фрагмента, полученного по правилу алмазного выхода.
  2. Общее количество фрагментов, полученных с помощью алгоритма, может отличаться от того, которое получено по правилу алмазного выхода, не более чем на один.
  3. Для строки x-major нельзя создать два фрагмента, которые лежат в одном столбце координат окна (для строки y-major два фрагмента не могут появляться в одной строке).
  4. Если два линейных сегмента имеют общую конечную точку, и оба сегмента имеют либо x-мажор (оба слева направо или оба справа налево), либо y-мажор (оба снизу вверх или оба сверху до нижнего предела), то растеризация обоих сегментов не может привести к дублированию фрагментов, а также не может быть пропущен ни один фрагмент, чтобы нарушить непрерывность соединенных сегментов.

Итак, ответ заключается в том, что спецификация не требует объединения строк, как вы могли бы ожидать. Если бы все ваши линии были x-мажорными или все y-мажорными, то вышеприведенное правило # 4 даст вам ожидаемый результат, но в вашем прямоугольнике вы чередуетесь между линиями x-major и y-major.

Если вы хотите гарантировать соединенные линии без пропусков или перекрытий, вы должны выполнить рендеринг с GL_LINE_LOOP (или GL_LINE_STRIP для соединенной серии, которая не заканчивается там, где начинается) вместо GL_LINES.

5 голосов
/ 26 декабря 2010

Поскольку вы рисуете замкнутый многоугольник, вы можете использовать GL_LINE_LOOP.

3 голосов
/ 26 декабря 2010

В результате лучше всего рисовать линии, используя GL_QUADS.Не так просто, как использование GL_LINES, но это работает:

glBegin(GL_QUADS);

    glColor3b(bRed, bGreen, bBlue);

    // Draw the top line
    glVertex2i(left, top);
    glVertex2i(right + 1, top);
    glVertex2i(right + 1, top + 1);
    glVertex2i(left, top + 1);

    // Draw the right line
    glVertex2i(right, top);
    glVertex2i(right + 1, top);
    glVertex2i(right + 1, bottom + 1);
    glVertex2i(right, bottom);

    // Draw the bottom line
    glVertex2i(left, bottom);
    glVertex2i(right + 1, bottom);
    glVertex2i(right + 1, bottom + 1);
    glVertex2i(left, bottom + 1);

    // Draw the left line
    glVertex2i(left, top);
    glVertex2i(left + 1, top);
    glVertex2i(left + 1, bottom + 1);
    glVertex2i(left, bottom);

glEnd();
1 голос
/ 26 декабря 2010

Я не мог решить ее полностью, но эти ссылки немного помогли тем, у кого была такая же проблема ... Я понял, что это широкая проблема, с которой сталкиваются многие люди (и обидно, что такая мощная библиотека делает этотак сложно выполнить такую ​​примитивную операцию, как рисование линии с точностью до пикселя).

http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=235566 http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=237621

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...