遮挡多边形外的所有内容 [英] Black out everything outside a polygon

查看:111
本文介绍了遮挡多边形外的所有内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一张地图,为简单起见,我们说它只是一个纹理.在此地图的顶部,我有一个多边形,指示用户必须遵循的路线.

I have a map, for simplicity let's say it's just a single texture. On top of this map, I have a polygon which indicates the route that the user must follow.

我想要的是在多边形黑色之外绘制所有内容.或者,当然只在多边形内部绘制东西.

What I want is to draw everything outside the polygon black. Or, of course to only draw things inside the polygon.

为了更好地解释,我拍了张照片.蓝线定义了多边形,每个角都是多边形中的一个点.带黄线的红色是我要从图片中涂黑的部分,只留下带紫色线的红色.多边形从A开始,在B结束.

To explain it better I made a picture. The blue lines define the polygon, with each corner being a point in the polygon. The red with yellow lines is the part I want to black out of the picture, and only leave the red with the purple lines. The polygon starts from A and ends at B.

推荐答案

此处的主要挑战是您需要绘制一个非凸多边形,OpenGL不直接支持该多边形.一种绘制方法是将其分解为三角形.根据您对多边形形状的了解程度以及它的约束程度,这可能很容易.对于一般的非凸多边形,这会有些痛苦.但是,如果您搜索诸如多边形三角剖分"之类的关键字,则可以找到一些算法.

The main challenge here is that you need to draw a non-convex polygon, which is not directly supported by OpenGL. One approach for drawing it is to break it down into triangles. Depending on how much you know about the shape of the polygon, and how constraint it is, this might be fairly easy. For a general non-convex polygon, it's slightly painful. But there are algorithms you can find if you search for keywords like "polygon triangulation".

OpenGL还有另一种适用于此类用例的机制:模板缓冲区.您可以在《红皮书》中的使用模板绘制填充,凹面的多边形中找到有关此方法的说明.缓冲.主要思想是可以绘制具有任意原点和多边形顶点的三角形扇.多边形内部的像素将被绘制奇数次,而多边形外部的像素将被绘制偶数次.模板缓冲区用于跟踪每个像素绘制次数的奇/偶计数.

OpenGL has another mechanism that works great for these kinds of use cases: stencil buffers. You can find an explanation of this approach in the Red Book under Drawing Filled, Concave Polygons Using the Stencil Buffer. The main idea is that you 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 of how many times each pixel is drawn.

概述主要步骤:

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

  1. While setting up your context and drawing surface, make sure that you request a configuration with a stencil buffer.
  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, giving us the odd/even count.

    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 your polygon corners, the sequence of vertices for the GL_TRIANGLE_FAN draw call is:

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

    您可以在此过程中使用简单的着色器,因为甚至没有写入颜色值.

    You can use a trivial shader 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);
    

  • 绘制全部内容.仅将绘制多边形轮廓内的零件,其余的将通过模具测试消除.

  • Draw your entire content. Only the part within the polygon outline will be rendered, the rest is eliminated by the stencil test.

    这篇关于遮挡多边形外的所有内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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