如何强制openGL绘制非凸填充多边形

hen*_*sti 0 c opengl drawing polygon

多边形以凸起形状绘制似乎是标准.请参阅stackoverflow.com/questions/15556929/open-gl-polygon但是,如果我选择填充它,则不适合我.如何在保持我定义的形状的同时填充多边形?

void drawFloor(){
    // White
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // GL_LINE works the way I want it too
    //glDisable(GL_POLYGON_SMOOTH); // has no effect :(
    glBegin(GL_POLYGON);
    glColor3f(1.0, 1.0, 1.0);
    glVertex3f(0, 0, 0); //0
    glVertex3f(2*boxSize, 0, 0); //1
    glVertex3f(2 * boxSize, -boxSize, 0); //2
    glVertex3f(5 * boxSize, -boxSize, 0); //3
    glVertex3f(5 * boxSize, 4 * boxSize, 0); //4
    glVertex3f(6 * boxSize, 4 * boxSize, 0); //5
    glVertex3f(6 * boxSize, 6 * boxSize, 0); //6
    glVertex3f(0 * boxSize, 6 * boxSize, 0); //7
    glVertex3f(0 * boxSize, 2 * boxSize, 0); //8
    glVertex3f(1 * boxSize, 2 * boxSize, 0); //9
    glVertex3f(1 * boxSize, 4 * boxSize, 0); //10
    glVertex3f(2 * boxSize, 4 * boxSize, 0); //11
    glVertex3f(2 * boxSize, 3 * boxSize, 0); //12
    glVertex3f(3 * boxSize, 3 * boxSize, 0); //13
    glVertex3f(3 * boxSize, 2 * boxSize, 0); //14
    glVertex3f(2 * boxSize, 2 * boxSize, 0); //15
    glVertex3f(2 * boxSize, 1 * boxSize, 0); //16
    glVertex3f(0, 1 * boxSize, 0); //17

    glEnd();
}
Run Code Online (Sandbox Code Playgroud)

此代码导致:

http://postimg.org/image/o4wt9ij33/与GL_LINE http://postimg.org/image/l31fltgkf/与GL_FILL

我只想填充多边形的内部,保持版本的形状与GL_LINE.我没想到GL_FILL的输出会如此不同.

我想要的(用MS绘制):http:// postimg.org/image/d3gbf613d/

我正在使用Win7 + Visula studio express2013 + Renderer Intel HD Graphics版本:3.1.0 - Bulid 8.15.10.2509+ GLSL版本1.40

Ret*_*adi 5

注意:这个答案与我最近对类似问题的答案共享内容:将多边形外部的所有内容涂黑.我没有将这些问题提名为重复,因为它们听起来不同,并且可能有不同的答案,即使这个问题大致相同.

绘制非凸多边形的一种方法是将它们分解为三角形.有许多算法可以做到这一点,可以通过搜索"多边形三角测量"等关键字找到.

OpenGL还有另一种适用于此的机制:模板缓冲区.这种方法的解释在红皮书下的绘图填充,凹面多边形使用模板缓冲区.主要思想是可以绘制具有任意原点和多边形顶点的三角形扇形.然后,多边形内部的像素将被绘制奇数次,而多边形外部的像素将被绘制偶数次.模板缓冲区用于跟踪奇数/偶数计数.

概述主要步骤:

  1. 在设置上下文和绘图表面时,请确保请求具有模板缓冲区的配置.
  2. 在绘图过程中,清除模板缓冲区和颜色缓冲区,并启用模板测试.

    glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glEnable(GL_STENCIL_TEST);
    
    Run Code Online (Sandbox Code Playgroud)
  3. 设置渲染过程的状态,计算像素是否呈现奇数/偶数次.请注意,这只能写入模板缓冲区,因此禁用了颜色写入.关键部分是GL_INVERT模板操作,它在每次渲染一个像素时翻转模板值,最终在模板缓冲区中存储奇数/偶数.

    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    glStencilFunc(GL_ALWAYS, 0, 1);
    glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT);
    glStencilMask(1);
    
    Run Code Online (Sandbox Code Playgroud)
  4. 渲染三角形扇形,其中任意点(例如(0.0,0.0))作为第一个顶点,多边形角点作为剩余顶点.必须关闭多边形,因此第一个和最后一个多边形角必须相同.如果p1,p2,...,pN是多边形角,则GL_TRIANGLE_FAN绘制调用的顶点序列为:

    (0.0f, 0.0f), p1, p2, ... , pN, p1
    
    Run Code Online (Sandbox Code Playgroud)

    由于甚至没有写入颜色值,因此可以使用普通的着色器进行此过程.

  5. 再次启用颜色写入,并设置模板测试属性以仅渲染在上一次传递中呈现奇数次数的像素.

    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    glStencilFunc(GL_EQUAL, 1, 1);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    
    Run Code Online (Sandbox Code Playgroud)
  6. 绘制覆盖多边形整个区域的几何图形,可能还有更多.例如,这可以是来自步骤4的三角形扇形,或者是多边形的边界框.仅渲染多边形轮廓内的零件,其余部分通过模板测试消除.