如何强制openGL绘制非凸填充多边形 [英] How to force openGL to draw a non-convex filled polygon

查看:322
本文介绍了如何强制openGL绘制非凸填充多边形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

It seems to be the standart that polygon are drawn in a convex shape. See stackoverflow.com/questions/15556929/open-gl-polygon However it is not for me if I choose it to be filled. How can I have my polygon filled while maintaining the shape I defined?

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

此代码导致:

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

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

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

I want only the inside of the polygon filled, keeping the shape of the version with the GL_LINE. I did not expect the output of GL_FILL to be so different.

我想要的东西(用MS paint创建): http://postimg.org/image/d3gbf613d/

What I want (created with MS paint): http:// postimg.org/image/d3gbf613d/

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

I am using Win7+ Visula studio express2013+ Renderer Intel HD Graphics Version: 3.1.0 - Bulid 8.15.10.2509+ GLSL Version 1.40

推荐答案

注意:此答案与我对以下类似问题的最新答案的内容相同:

Note: This answer shares content with my recent answer to a similar question here: Black out everything outside a polygon. I did not nominate the questions as duplicates because they sound different, and could potentially have different answers, even though this one happens to be mostly the same.

绘制非凸多边形的一种方法是将其分解为三角形.可以通过搜索诸如多边形三角剖分"之类的关键字找到许多算法.

One approach for drawing non-convex polygons is to break them down into triangles. There are a number of algorithms that can do this, which can be found by searching for keywords like "polygon triangulation".

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

OpenGL has another mechanism that works great for this: stencil buffers. An explanation of this approach is in the Red Book under Drawing Filled, Concave Polygons Using the Stencil Buffer. The main idea is that one can draw a triangle fan with an arbitrary origin and your polygon vertices. The pixels that are inside the polygon will then be drawn an odd number of times, while the pixels outside the polygons are drawn an even number of times. The stencil buffer is used to track the odd/even count.

概述主要步骤:

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

  1. While setting up the context and drawing surface, make sure that a configuration with a stencil buffer is requested.
  2. During drawing, clear the stencil buffer along with the color buffer, and enable the stencil test.

glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glEnable(GL_STENCIL_TEST);

  • 设置渲染过程的状态,该过程计算是否将像素渲染为奇数/偶数次.请注意,这只能写入模板缓冲区,因此颜色写操作被禁用.关键部分是模具op的GL_INVERT,它在每次渲染像素时翻转模具值,最终将奇/偶计数存储在模具缓冲区中.

  • Set up state for the render pass that counts if pixels are rendered an odd/even number of times. Note that this must only write to the stencil buffer, so color writes are disabled. The key part is the GL_INVERT for the stencil op, which flips the stencil value each time a pixel is rendered, which ends up storing the odd/even count in the stencil buffer.

    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    glStencilFunc(GL_ALWAYS, 0, 1);
    glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT);
    glStencilMask(1);
    

  • 渲染具有任意点的三角形风扇,例如(0.0,0.0)作为第一个顶点,而多边形角作为剩余的顶点.多边形必须是封闭的,因此第一个和最后一个多边形角必须相同.如果p1,p2,...,pN是多边形角,则GL_TRIANGLE_FAN绘制调用的顶点顺序为:

  • Render a triangle fan with an arbitrary point, e.g. (0.0, 0.0), as the first vertex, and the polygon corners as the remaining vertices. The polygon must be closed, so the first and last polygon corner must be the same. If p1, p2, ... , pN are the polygon corners, the sequence of vertices for the GL_TRIANGLE_FAN draw call is:

    (0.0f, 0.0f), p1, p2, ... , pN, p1
    

    一个简单的着色器可以用于此过程,因为甚至没有写入颜色值.

    A trivial shader can be used for this pass since the color value is not even written.

    再次启用颜色写入功能,并设置模板测试属性以仅渲染在上一遍中渲染了奇数次的像素.

    Enable color writes again, and set up the stencil test attributes to render only pixels that were rendered an odd number of times in the previous pass.

    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    glStencilFunc(GL_EQUAL, 1, 1);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    

  • 绘制覆盖多边形整个区域甚至更多区域的几何图形.例如,这可以是步骤4中的三角形扇形,也可以是多边形的边界框.只会渲染多边形轮廓内的部分,其余的将通过模具测试消除.

  • Draw geometry that covers the entire area of the polygon, and possibly more. This can for example be the triangle fan from step 4, or a bounding box of the polygon. Only the part within the polygon outline will be rendered, the rest is eliminated by the stencil test.

    这篇关于如何强制openGL绘制非凸填充多边形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆