我有一张地图,为简单起见,我们说它只是一个纹理。在这张地图的顶部,我有一个多边形,表示用户必须遵循的路线。
我想要的是在多边形黑色之外绘制所有内容。或者,当然只在多边形内绘制东西。
为了更好地解释,我拍了一张照片。蓝线定义多边形,每个角都是多边形中的一个点。带有黄色线条的红色是我想要从图片中黑化的部分,只留下带有紫色线条的红色。多边形从A开始,到B结束。
答案 0 :(得分:8)
这里的主要挑战是你需要绘制一个非凸多边形,OpenGL不直接支持它。绘制它的一种方法是将其分解为三角形。根据您对多边形形状的了解程度以及它的约束程度,这可能相当容易。对于一般的非凸多边形,它有点痛苦。但是,如果您搜索“多边形三角测量”等关键字,您可以找到算法。
OpenGL有另一种机制,适用于这些用例:模板缓冲区。您可以在Drawing Filled, Concave Polygons Using the Stencil Buffer下的红皮书中找到对此方法的解释。主要思想是您可以绘制具有任意原点和多边形顶点的三角形扇形。然后,多边形内部的像素将被绘制奇数次,而多边形外部的像素将被绘制偶数次。模板缓冲区用于跟踪每个像素绘制的奇数/偶数计数。
概述主要步骤:
在绘图过程中,清除模板缓冲区和颜色缓冲区,然后启用模板测试。
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glEnable(GL_STENCIL_TEST);
设置渲染过程的状态,计算像素是否呈现奇数/偶数次。请注意,这只能写入模板缓冲区,因此禁用了颜色写入。关键部分是模板操作的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);
渲染具有任意点的三角形扇形,例如(0.0,0.0),作为第一个顶点,多边形角作为剩余的顶点。必须关闭多边形,因此第一个和最后一个多边形角必须相同。如果p1,p2,...,pN是您的多边形角,则GL_TRIANGLE_FAN
绘制调用的顶点序列为:
(0.0f, 0.0f), p1, p2, ... , pN, p1
您可以为此过程使用一个简单的着色器,因为甚至没有写入颜色值。
再次启用颜色写入,并设置模板测试属性以仅渲染在上一次传递中呈现奇数次数的像素。
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glStencilFunc(GL_EQUAL, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
绘制整个内容。仅渲染多边形轮廓内的零件,其余部分通过模板测试消除。