Как я могу сделать GL_LINE_L OOP сглаживание? - PullRequest
1 голос
/ 07 января 2020

Вот некоторый код openGL, который я создал. Рутина двух боковых домов. Я пытаюсь сделать только один из этих домов, которые выглядят хорошо, без пикселей. Я хочу использовать сглаживание, но я не могу понять, почему он не работает .. Любая помощь?

void myDisplay()
{
    //glClear(GL_COLOR_BUFFER_BIT);
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glColor3f(0.0, 0.0, 0.0);
    glBegin(GL_LINE_LOOP);
    glVertex3f(0, 0, 0); // XYZ middle, top
    glVertex3f(-0.05, -.15, 0); // XYZ left, bottom
    glVertex3f(.15, .05, 0); // XYZ right, bottom
    glEnd();
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glBegin(GL_LINE_LOOP);
    glVertex3f(0, -.1, 0); // XYZ left, top
    glVertex3f(.1, 0, 0); // XYZ right, top
    glVertex3f(0.2, -.1, 0); // XYZ right, bottom
    glVertex3f(0.1, -.2, 0); // XYZ left, bottom
    glEnd();
    glEnable(GL_BLEND);
    glEnable(GL_LINE_SMOOTH);
    glEnable(GL_POLYGON_SMOOTH);

    glEnable(GL_POINT_SMOOTH);
    glBegin(GL_LINE_LOOP);
    glVertex3f(-.2, 0.1, 0); // XYZ left, top
    glVertex3f(-.1, .2, 0); // XYZ right, top
    glVertex3f(0, .1, 0); // XYZ right, bottom
    glVertex3f(-.1, 0, 0); // XYZ left, bottom
    glEnd();
    glBegin(GL_LINE_LOOP);
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
    glEnable(GL_ALPHA_TEST);
    glAlphaFunc(GL_ALWAYS, 0);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_POLYGON_SMOOTH);
    glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE);
    glEnable(GL_BLEND);
    glVertex3f(-.2, .2, 0); // XYZ middle, top
    glVertex3f(-.25, .05, 0); // XYZ left, bottom
    glVertex3f(-.05, 0.25, 0); // XYZ right, bottom
    glEnd();
    glFlush();
}

int main(int argc,
    char** argv)
{
    glutInit(&argc, argv);
    glutCreateWindow( "basic template 1" );
    glutDisplayFunc( myDisplay );
    glutMainLoop();
}

Ответы [ 3 ]

0 голосов
/ 07 января 2020

В основном, это, вероятно, не поддерживается. К сожалению, glHint - это просто подсказка (никто не должен ее реализовывать).

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

int main(int argc,
    char** argv)
{
   glutInit(&argc, argv);
   glutSetOption(GLUT_MULTISAMPLE, 8);
   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_MULTISAMPLE);
   glutCreateWindow("basic template 1");
   glutDisplayFunc(myDisplay);
   glEnable(GL_MULTISAMPLE);
   glutMainLoop();
}

Также убедитесь, что вы удалили вызов 'glutInitDisplayMode' в своей функции отображения (Вы должны вызывать его только один раз, перед созданием окна).

0 голосов
/ 07 января 2020

Существует несколько способов сделать сглаживание в OpenGL. Некоторые из них описаны здесь

. Для вашего примера я предлагаю переместить все функции инициализации в основную функцию. В вашем исходном примере glClear() отсутствовал и установил перед функцией прозрачного цвета. Это делает экран черным.

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

Я также предлагаю собрать их вместе и до реальных функций рисования. Вы также не должны помещать функции включения / выключения между блоками glBegin/glEnd. Это также помогает для ясности кода.

Я изменил цвет одного дома, поэтому вы видите черный дом без сглаживания, но синий дом имеет.

void myDisplay()
{
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(0.0, 0.0, 0.0);

    glDisable(GL_BLEND);
    glDisable(GL_POINT_SMOOTH);
    glDisable(GL_LINE_SMOOTH);
    glDisable(GL_POLYGON_SMOOTH);

    glColor3f(0, 0, 0);
    glBegin(GL_LINE_LOOP);
    glVertex3f(0, 0, 0); // XYZ middle, top
    glVertex3f(-0.05, -.15, 0); // XYZ left, bottom
    glVertex3f(.15, .05, 0); // XYZ right, bottom
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(0, -.1, 0); // XYZ left, top
    glVertex3f(.1, 0, 0); // XYZ right, top
    glVertex3f(0.2, -.1, 0); // XYZ right, bottom
    glVertex3f(0.1, -.2, 0); // XYZ left, bottom
    glEnd();

    glColor3f(0, 0, 1);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glEnable(GL_POINT_SMOOTH);
    glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);

    glEnable(GL_LINE_SMOOTH);
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);

    glEnable(GL_POLYGON_SMOOTH);
    glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);

    glBegin(GL_LINE_LOOP);
    glVertex3f(-.2, 0.1, 0); // XYZ left, top
    glVertex3f(-.1, .2, 0); // XYZ right, top
    glVertex3f(0, .1, 0); // XYZ right, bottom
    glVertex3f(-.1, 0, 0); // XYZ left, bottom
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(-.2, .2, 0); // XYZ middle, top
    glVertex3f(-.25, .05, 0); // XYZ left, bottom
    glVertex3f(-.05, 0.25, 0); // XYZ right, bottom
    glEnd();

    glFlush();
}




int main(int argc,     char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutCreateWindow("basic template 1");
    glutDisplayFunc(&myDisplay);
    glutMainLoop();
}
Обновление:

Другие ответы "технически правильны", но я сделал несколько предостережений и наблюдений:

  • glEnable(GL_MULTISAMPLING) больше не поддерживается в новых стандартах OpenGL ( Раньше он был до 1,3 IIR C). Возможность использования по-прежнему зависит от вашей фактической реализации.
  • функция glutSetOption() доступна только в «freeglut» при использовании #include "GL/freeglut.h", а не в оригинальном glut.h. Но мое наблюдение на Windows состоит в том, что нет никакой разницы между указанием мультисэмплинга или нет. Так что я предполагаю, что это «по умолчанию включено».
0 голосов
/ 07 января 2020

Нельзя вызывать что-либо между glBegin / glEnd, кроме тех операций, которые устанавливают атрибуты вершины и задают вершину (glVertex, glColor, glNormal, glTexCoord, ...).

Для Мультисэмплирование сглаживания , Флаг GLUT_MULTISAMPLE должен быть установлен в glutInitDisplayMode. При желании количество образцов может быть установлено с помощью glutSetOption. Это должно быть сделано до glutCreateWindow:

glutSetOption(GLUT_MULTISAMPLE, 8);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_MULTISAMPLE);
glutCreateWindow( "basic template 1" );

По умолчанию мультисэмплинг включен. Его можно включить и отключить с помощью glEnable(GL_MULTISAMPLE) / glDisable(GL_MULTISAMPLE):

void myDisplay()
{
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glColor3f(0.0, 0.0, 0.0);

    glDisable(GL_MULTISAMPLE);

    glBegin(GL_LINE_LOOP);
    glVertex3f(0, 0, 0); // XYZ middle, top
    glVertex3f(-0.05, -.15, 0); // XYZ left, bottom
    glVertex3f(.15, .05, 0); // XYZ right, bottom
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(0, -.1, 0); // XYZ left, top
    glVertex3f(.1, 0, 0); // XYZ right, top
    glVertex3f(0.2, -.1, 0); // XYZ right, bottom
    glVertex3f(0.1, -.2, 0); // XYZ left, bottom
    glEnd();

    glEnable(GL_MULTISAMPLE);

    glBegin(GL_LINE_LOOP);
    glVertex3f(-.2, 0.1, 0); // XYZ left, top
    glVertex3f(-.1, .2, 0); // XYZ right, top
    glVertex3f(0, .1, 0); // XYZ right, bottom
    glVertex3f(-.1, 0, 0); // XYZ left, bottom
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(-.2, .2, 0); // XYZ middle, top
    glVertex3f(-.25, .05, 0); // XYZ left, bottom
    glVertex3f(-.05, 0.25, 0); // XYZ right, bottom
    glEnd();
    glFlush();
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);

    glutSetOption(GLUT_MULTISAMPLE, 8);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_MULTISAMPLE);
    glutCreateWindow( "basic template 1" );
    glutDisplayFunc( myDisplay );
    glutMainLoop();
}
...