如何在 OpenGL 中用圆进行裁剪

发布于 2025-01-07 18:09:06 字数 833 浏览 0 评论 0原文

我想知道是否可以在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();

我得到的是在中心绘制的一个圆,但我想获得它的互补...

I'm wondering if it is possible to simulate the effect of looking through the keyhole in OpenGL.

I have my 3D scene drawn but I want to make everythig black everything except a central circle.

I tried this solution but its doing the completely opposite of what I want:

// 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();

What I get is a circle drawn in the center, but I would like to obtain its complementary...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

潇烟暮雨 2025-01-14 18:09:06

与 OpenGL 中的其他所有内容一样,有几种方法可以做到这一点。这是我脑海中的两个。

使用圆形纹理:(推荐)

  1. 绘制场景。
  2. 切换到正交投影,并使用中心有白色圆圈的纹理在整个屏幕上绘制一个四边形。使用适当的混合函数:

    glEnable(GL_BLEND);
    glBlendFunc(GL_ZERO, GL_SRC_COLOR);
    /* 绘制一个全屏四边形,中心有一个白色圆圈 */
    

或者,您可以使用像素着色器来生成圆形形状。

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

  1. 清除模板缓冲区,然后在其中绘制圆圈。

    glEnable(GL_STENCIL_TEST);
    glStencilFunc(GL_ALWAYS, 1, 1);
    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
    /* 画圆 */
    
  2. 为场景的其余部分启用模板测试。

    glEnable(GL_STENCIL_TEST)
    glStencilFunc(GL_EQUAL, 1, 1);
    glStencileOp(GL_KEEP, GL_KEEP, GL_KEEP);
    /* 绘制场景 */
    

脚注:我建议避免在代码中的任何点使用立即模式,而使用数组。这将提高代码的兼容性、可维护性、可读性和性能——这是所有领域的胜利。

Like everything else in OpenGL, there are a few ways to do this. Here are two off the top of my head.

Use a circle texture: (recommended)

  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 */
    

Alternatively, you can use a pixel shader to generate the circular shape.

Use a stencil test: (not recommended, but it may be easier if you don't have textures or shaders)

  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 */
    

Footnote: I recommend avoiding use of immediate mode at any point in your code, and using arrays instead. This will improve the compatibility, maintainability, readibility, and performance of your code --- a win in all areas.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文