【问题标题】:OpenGL stencil buffer concave polygonOpenGL模板缓冲区凹多边形
【发布时间】:2014-01-17 13:30:11
【问题描述】:

我正在尝试做this 的例子。

我仍然无法理解它是如何工作的,而且我在可视化代码的样子时遇到了困难。

我偶然发现了this post,这是我认为我能找到的最接近的。

从红皮书链接,我怎样才能做一个“两遍算法”来获得所需的输出?如何使用GL_INVERT 并检查像素是否被偶数覆盖?

我以某种方式设法理解了模板如何为凹多边形工作,但我现在的问题是多边形渲染不正确。

http://img.photobucket.com/albums/v442/ardo/ScreenShot2013-12-30at24155PM.png

我绘制的位置在一个帧缓冲区中,设置如下:

            //multisample
            glGenRenderbuffersEXT(1, &colorBuffer);
            glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorBuffer);
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, multisampling, GL_RGBA,800, 600);

            //multi sample depth
            glGenRenderbuffersEXT(1, &depthBuffer);
            glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, multisampling, GL_DEPTH24_STENCIL8, 800, 600);

            //multisamplefbo
            glGenFramebuffersEXT(1, &mFBO);
            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
            glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, colorBuffer);
            glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER_EXT, depthBuffer);

那我的绘图代码是:

glEnable(GL_STENCIL_TEST);         
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 
glStencilFunc(GL_ALWAYS, 0x1, 0x1);
glStencilOp(GL_KEEP, GL_INVERT, GL_INVERT);

glBegin(GL_TRIANGLE_FAN);

glVertex3f(1.396900,3.130690,0);
glVertex3f(2.034830,2.466900,0);
glVertex3f(2.486338,2.441036,0);
glVertex3f(2.802204,2.437803,0);
glVertex3f(2.910181,2.447098,0);
glVertex3f(2.957240,2.466900,0);
glVertex3f(3.019335,2.552570,0);
glVertex3f(3.130733,2.673799,0);
glVertex3f(3.284830,2.828970,0);
glVertex3f(3.474490,3.087590,0);
glVertex3f(4.319320,2.596210,0);
glVertex3f(4.508980,2.147930,0);
glVertex3f(4.714798,1.866680,0);
glVertex3f(4.907215,1.620586,0);
glVertex3f(5.101651,1.397930,0);
glVertex3f(5.186114,1.317364,0);
glVertex3f(5.254869,1.269024,0);
glVertex3f(5.302510,1.261700,0);
glVertex3f(5.323633,1.304180,0);
glVertex3f(5.312832,1.405254,0);
glVertex3f(5.264703,1.573711,0);
glVertex3f(5.173841,1.818340,0);
glVertex3f(5.034840,2.147930,0);
glVertex3f(4.875695,2.492816,0);
glVertex3f(4.727900,2.780675,0);
glVertex3f(4.591307,3.016304,0);
glVertex3f(4.465765,3.204503,0);
glVertex3f(4.351127,3.350070,0);
glVertex3f(4.247241,3.457803,0);
glVertex3f(4.153958,3.532502,0);
glVertex3f(4.071129,3.578965,0);
glVertex3f(3.998605,3.601990,0);
glVertex3f(3.936235,3.606376,0);
glVertex3f(3.841363,3.578427,0);
glVertex3f(3.766900,3.510000,0);
glVertex3f(2.974490,3.458280,0);
glVertex3f(2.672770,2.958280,0);
glVertex3f(2.379670,3.070350,0);
glVertex3f(1.853810,3.303110,0);
glVertex3f(1.396910,3.303110,0);
glVertex3f(1.396910,3.130690,0);
glVertex3f(1.396900,3.130690,0);
glVertex3f(1.396900,3.130690,0);

   glEnd();


glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 
glStencilFunc(GL_EQUAL, 0x1, 0x1);                  
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glColor3f(1,0,1);
glBegin(GL_TRIANGLE_FAN);

glVertex3f(1.396900,3.130690,0);
glVertex3f(2.034830,2.466900,0);
glVertex3f(2.486338,2.441036,0);
glVertex3f(2.802204,2.437803,0);
glVertex3f(2.910181,2.447098,0);
glVertex3f(2.957240,2.466900,0);
glVertex3f(3.019335,2.552570,0);
glVertex3f(3.130733,2.673799,0);
glVertex3f(3.284830,2.828970,0);
glVertex3f(3.474490,3.087590,0);
glVertex3f(4.319320,2.596210,0);
glVertex3f(4.508980,2.147930,0);
glVertex3f(4.714798,1.866680,0);
glVertex3f(4.907215,1.620586,0);
glVertex3f(5.101651,1.397930,0);
glVertex3f(5.186114,1.317364,0);
glVertex3f(5.254869,1.269024,0);
glVertex3f(5.302510,1.261700,0);
glVertex3f(5.323633,1.304180,0);
glVertex3f(5.312832,1.405254,0);
glVertex3f(5.264703,1.573711,0);
glVertex3f(5.173841,1.818340,0);
glVertex3f(5.034840,2.147930,0);
glVertex3f(4.875695,2.492816,0);
glVertex3f(4.727900,2.780675,0);
glVertex3f(4.591307,3.016304,0);
glVertex3f(4.465765,3.204503,0);
glVertex3f(4.351127,3.350070,0);
glVertex3f(4.247241,3.457803,0);
glVertex3f(4.153958,3.532502,0);
glVertex3f(4.071129,3.578965,0);
glVertex3f(3.998605,3.601990,0);
glVertex3f(3.936235,3.606376,0);
glVertex3f(3.841363,3.578427,0);
glVertex3f(3.766900,3.510000,0);
glVertex3f(2.974490,3.458280,0);
glVertex3f(2.672770,2.958280,0);
glVertex3f(2.379670,3.070350,0);
glVertex3f(1.853810,3.303110,0);
glVertex3f(1.396910,3.303110,0);
glVertex3f(1.396910,3.130690,0);
glVertex3f(1.396900,3.130690,0);
glVertex3f(1.396900,3.130690,0);

    glEnd();

glDisable(GL_STENCIL_TEST);

我的多重采样设置方式在这里(这是在绘图之前)

[self checkError];
        glEnable(GL_DEPTH_TEST);
        [self checkError];
        glDepthMask(GL_TRUE);
        [self checkError];
        glDepthFunc(GL_LESS);
        [self checkError];
        glClearDepth(10000.0);
        [self checkError];
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
        [self checkError];

        if(multisampling != 0){
            //Set multisampled framebuffer
            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

            //Antialiasing functions
            glEnable (GL_POLYGON_SMOOTH);
            glEnable (GL_BLEND);
            glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            glHint (GL_POLYGON_SMOOTH_HINT, GL_NICEST);
            glLineWidth (1.5);
        }

        glDisable(GL_CULL_FACE);

还有我的 blit 调用:

glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, mFBO);
            glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, currentFramebuffer);

            glBlitFramebuffer(0, 0, 800, 600, 0, 0, 800, 600, GL_COLOR_BUFFER_BIT, GL_NEAREST);

            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
            glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);

            glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, currentFramebuffer);
            glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, currentFramebuffer);
            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, currentFramebuffer);

【问题讨论】:

  • 平滑多边形应该使用不同于您当前使用的混合功能。它们在目标 Alpha 通道中累积覆盖范围(因此您还需要存储 Alpha 的像素格式),GL_SRC_ALPHA_SATURATEGL_ONE 最适合平滑多边形。当然,由于硬件通常不会加速这一点,而且您已经在使用多重采样,我想说停止启用GL_POLYGON_SMOOTH
  • @AndonM.Coleman 我尝试删除 GL_POLYGON_SMOOTH 但我仍然得到这个:img.photobucket.com/albums/v442/ardo/…
  • 我并不是要暗示这会解决你的问题......只是它是一个问题。顺便说一句,使用单采样渲染缓冲区会改变什么吗?
  • @AndonM.Coleman 哦,我明白了,我尝试了没有多重采样并降低多重采样,但问题仍然存在。

标签: c++ opengl polygon stencil-buffer concave


【解决方案1】:

你没有得到什么?该示例从清除为 0x00 的模板缓冲区开始,每次绘制片段(无论它通过还是失败深度/模板测试)它都会执行模板缓冲区的按位反转(例如 ~0x00 --> 0xff)。如果你这样做奇数次,模板缓冲区将非零,但如果你有偶数个片段,它将为零。

可能会造成混淆的一些事情是使用 1 作为模板测试的位掩码和第二遍中的模板操作。这有效地将测试限制为单个位。换句话说,我之前提到的位翻转只会发生在位 1。因此,您实际上可以将偶数/奇数测试简化为单个位的测试......如果模板缓冲区存储了 的值1 然后你画了奇数个碎片。如果它存储的值是0,那么你画的是一个偶数。

您的示例中的第二遍实际上进行了我描述的精确模板测试。它为 1 测试模板缓冲区,如果第一位 != 1 则模板测试失败。

// The stencil op below is a convoluted way of clearing the stencil buffer
glStencilOp   (GL_ZERO,  GL_ZERO, GL_ZERO);
glStencilFunc (GL_EQUAL, 1,       1);       // Test: (Stencil & 1) == 1

【讨论】:

  • 我用我的输出更新了我的问题。我仍然对整个模板感到困惑,这就是我想出的。但它没有正确渲染。
  • @ardowz:你为什么要更改模板操作。到GL_KEEP, GL_KEEP, GL_KEEP?您在代码中的哪个位置实际设置了模板清除值并清除了模板缓冲区?您更新后的代码添加的问题多于回答的问题。您能否包含更多模板缓冲区设置代码,以及您在哪里执行 MSAA 解析 blit(例如 glBlitFramebuffer (...))等。
  • 我正在尝试使用和不使用 stencilOp 更改。不知何故,两者都会产生不同的结果,使用 stencilOp 它提供了类似的输出,而没有 stencilOp,它提供了更清晰的输出:
猜你喜欢
  • 1970-01-01
  • 2018-06-23
  • 2012-07-11
  • 1970-01-01
  • 2013-03-11
  • 2011-04-16
相关资源
最近更新 更多