如何在OpenGL中裁剪圆形

4

我想知道在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

在OpenGL中,像其它一切一样,有几种方法可以做到这一点。以下是我脑海中的两种方法。

使用圆形纹理:(推荐)

  1. Draw the scene.
  2. Switch to an orthographic projection, and draw a quad over the entire screen using a texture which has a white circle at the center. Use the appropriate blending function:

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

你可以使用像素着色器来生成圆形。

使用模板测试:(虽然不建议,但如果你没有纹理或着色器可能会更容易)

  1. Clear the stencil buffer, and draw the circle into it.

    glEnable(GL_STENCIL_TEST);
    glStencilFunc(GL_ALWAYS, 1, 1);
    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
    /* draw circle */
    
  2. Enable the stencil test for the remainder of the scene.

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

注:我建议在代码的任何时候都避免使用即时模式,而使用数组。这将提高代码的兼容性、可维护性、易读性和性能——在所有方面都是一场胜利。


我用第二种方法解决了...这是我需要的资源:http://en.wikibooks.org/wiki/OpenGL_Programming/Stencil_buffer我不明白你所说的"immediate mode"是什么意思,你是指使用glVertex2f和其他基元吗? - linello
是的,glVertex2f以及其它相似函数都是即时模式。我强烈建议使用glVertexPointer/glDrawArrays/glDrawRangeElements等替代它们。把glVertex2f看作已经过时的古董,而将glVertexPointer视为“老方法”(但并没有那么老)。 - Dietrich Epp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接