Включение сглаживания в панели управления NVIDIA приводит к искажению линий в орфографической проекции

#opengl #drawing #antialiasing #nvidia #orthographic

#opengl #рисование #сглаживание #nvidia #ортогональный

Вопрос:

В этом приложении OpenGL, которое я разрабатываю для Windows 7 с Visual Studio, я попытался включить сглаживание на панели управления NVIDIA (только для application .exe).

Включение этого вызывает небольшое искажение линий / квадратов, нарисованных в ортогональной проекции.

Сглаживание отключено слева и включено справа:

проблема со сглаживанием

Как это можно исправить, сохранив сглаживание включенным?

В случае, если это уместно, вот как настраивается ортогональная проекция и как рисуется черная граница:

 void drawHeadsUpDisplay(void) {
    static int winWidth, winHeight;

    winWidth = glutGet(GLUT_WINDOW_WIDTH);
    winHeight = glutGet(GLUT_WINDOW_HEIGHT);
    glPushAttrib(GL_ENABLE_BIT);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_LIGHTING);

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    gluOrtho2D(0.0f, winWidth, winHeight, 0.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glBegin(GL_LINE_LOOP);
        glColor3f(0.0f, 0.0f, 0.0f);
        glVertex2f(winWidth - 41, 48);
        glVertex2f(winWidth - 41, winHeight - 48);
        glVertex2f(winWidth - 18, winHeight - 48);
        glVertex2f(winWidth - 18, 48);
    glEnd();

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);

    glPopAttrib();
}
  

Ответ №1:

У вас там 48 и 49 в направлении y. Без включенного сглаживания целочисленное округление из-за проекции скрывает разницу, но с включенным сглаживанием вы видите наклон. Просто измените на

 glBegin(GL_LINE_LOOP);
    glColor3f(0.0f, 0.0f, 0.0f);
    glVertex2f(winWidth - 41, 49);
    glVertex2f(winWidth - 41, winHeight - 49);
    glVertex2f(winWidth - 18, winHeight - 49);
    glVertex2f(winWidth - 18, 49);
glEnd();
  

(или 48 везде)

Комментарии:

1. Вы правы, но это только устраняет проблему наклона. Строки по-прежнему сглажены, а я этого не хочу. Ну, я делаю, в зависимости от ситуации. В этом я рисую вертикальную линию, где x является постоянным, почему линия размыта? Это то, чего я хочу избежать, но продолжаю поддерживать АА.

2. @Nazgulled: Скорее всего, само расположение линий не соответствует точному местоположению пикселя. При выключенном AA изображение отображается в ближайшем пикселе, а при включенном AA оно придает немного цвета пикселям с обеих сторон. Этот эффект был бы менее заметен, если бы вы использовали большую ширину линии, если это возможно.

3. @Drew Hall, @Nazgulled: Не так уж сложно сопоставить позиции линий с точными пикселями окна. Это практически та же проблема, что и пиксельный выбор субизображения текстуры. Но комментария будет недостаточно для объяснения. Я думаю, что сделаю это более длинным ответом после работы.

4. @Drew Hall: Почему это не в точном расположении пикселя? Я использую целые числа и указываю точные местоположения, вот чего я не понимаю. @datenwolf: Я был бы признателен.

5. Поскольку OpenGL не обрабатывает пиксели. Я предполагаю, что вы используете какой-нибудь glViewport (0,0, ширина, высота); glOrtho (0, ширина, 0, высота,-1,1); настройка для проекции. Возьмите лист бумаги в виде сетки. Окно просмотра выбирает ячейки сетки, но ортопроекция попадает не в центры ячеек сетки, а в линии сетки! Это нормально, если вы хотите отобразить текстуру с идеальной пикселизацией, потому что там вы столкнулись с той же проблемой в обратном порядке, и оба эффекта отменяются. Но в вашем случае этого не происходит. Вместо glOrtho(0,5/ ширина, width-1 0.5/ ширина, 0,5/высота, высота-1 0.5/ высота); должно сработать.

Ответ №2:

Использование линий в целом — не лучшая идея (вместо этого вам следует использовать текстурированные треугольники / прямоугольники.) но ваша проблема, вероятно, вызвана тем, что линии попадают между «центрами» фрагментов, как определено стандартом. Вероятно, вы можете облегчить (если не устранить полностью) проблему, сдвинув координаты на 0,5, предполагая, что вы используете ортогональную проекцию 1: 1.

Комментарии:

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

2. Поскольку центры пикселей в OpenGL находятся на (x 0,5, y 0,5), а не (x, y).

3. Я не думаю, что использую ортогональную проекцию 1: 1, но я не уверен. Я добавил более полный пример к моему первоначальному вопросу. Пожалуйста, взгляните.