Как обрезать круги в OpenGL - PullRequest
       46

Как обрезать круги в OpenGL

4 голосов
/ 21 февраля 2012

Мне интересно, возможно ли смоделировать эффект просмотра замочной скважины в OpenGL.

Моя 3D-сцена нарисована, но я хочу сделать все черным все, кроме центрального круга.

Я попробовал это решение, но оно полностью противоположно тому, что я хочу:

// here i draw my 3D scene 

// Begin 2D orthographic mode
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();

GLint viewport [4];
glGetIntegerv(GL_VIEWPORT, viewport);

gluOrtho2D(0, viewport[2], viewport[3], 0);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

// Here I draw a circle in the center of the screen
float radius=50;
glBegin(GL_TRIANGLE_FAN);
glVertex2f(x, y);
for( int n = 0; n <= 100; ++n )
{
    float const t = 2*M_PI*(float)n/(float)100;
    glVertex2f(x + sin(t)*r, y + cos(t)*r);
}
glEnd();

// end orthographic 2D mode
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();

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

1 Ответ

6 голосов
/ 21 февраля 2012

Как и все остальное в OpenGL, есть несколько способов сделать это. Вот два от макушки моей головы.

Используйте текстуру круга: (рекомендуется)

  1. Нарисуйте сцену.
  2. Переключитесь на ортогональную проекцию и нарисуйте четырехугольник по всему экрану, используя текстуру с белым кружком в центре. Используйте соответствующую функцию смешивания:

    glEnable(GL_BLEND);
    glBlendFunc(GL_ZERO, GL_SRC_COLOR);
    /* Draw a full-screen quad with a white circle at the center */
    

Кроме того, вы можете использовать пиксельный шейдер для создания круглой формы.

Используйте тест трафарета: (не рекомендуется, но может быть проще, если у вас нет текстур или шейдеров)

  1. Очистите буфер трафарета и нарисуйте в нем круг.

    glEnable(GL_STENCIL_TEST);
    glStencilFunc(GL_ALWAYS, 1, 1);
    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
    /* draw circle */
    
  2. Включить проверку трафарета для остальной части сцены.

    glEnable(GL_STENCIL_TEST)
    glStencilFunc(GL_EQUAL, 1, 1);
    glStencileOp(GL_KEEP, GL_KEEP, GL_KEEP);
    /* Draw the scene */
    

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

...