假设我有一个正方形'S'。我需要制作一个圆圈'C'以这样的方式通过它,即S将分开并且C将通过它。虽然我需要给它一个3D效果,2D也可以(至少我会先行一步)。 有没有办法使用一些内置功能或者翻译单个像素或对象的一部分?我不确定你是如何在物体内部绘制一个洞的,但是你可以用你背景的颜色制作一个洞的形状的物体,使它看起来像一个洞?但真正的问题是如何使方形分裂? (这两半会以某种方式分开然后重新加入)。
答案 0 :(得分:2)
好吧,因为“你希望圆圈随着时间的推移而移动(从一帧到另一帧),并且方块在圆圈所在的任何地方消失,而一旦是”,它只是在2D中,你可以为此使用模板缓冲区。
模板缓冲区基本上为每个像素存储一个整数值,并允许您更改此值并将其与新绘制的像素进行比较,以便从绘图中排除像素。所以我们要做的是将圆绘制到模板缓冲区(在圆形像素所在的任何地方将其设置为1)然后在没有绘制圆形像素的任何地方绘制正方形(模板缓冲区为0的地方)。与“通常”模板印刷方法的唯一区别在于,我们不会清除帧之间的模板缓冲区,因此无论圆圈曾经如何,它都会保留圆圈值。因此,当您随着时间的推移扫过屏幕上的圆圈时,不会在圆形像素曾经存在的任何地方绘制正方形(当然具有相同的时间离散误差,如绘制的像素应该是圆的,但不是因为它在帧之间移动得太快了。)
首先我们将圆圈绘制到模板缓冲区中(如果您只想将圆圈用于模板印刷而不是在屏幕上绘制实际圆圈,则可以使用glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
禁用颜色写入,但不要忘记之后重新启用颜色写入:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //but don't clear stencil
glEnable(GL_STENCIL_TEST); //use stenciling
glStencilFunc(GL_ALWAYS, 1, -1); //draw everywhere, use 1 as ref value
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); //set pixels to ref value (1)
//draw circle
glStencilFunc(GL_NOTEQUAL, 1, -1); //draw wherever not 1 (no circle pixels)
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); //leave stencil values unchanged
//draw square
这只是一个基本的例子。您也可以将模板缓冲区用于其他事情。此刻圆圈将改变模板值,无论它是否在另一个已经绘制的对象后面,但是可以通过更改glStencilOp
中的值来进行微调(它根据if配置如何更改模板值)模板测试失败,成功和深度测试失败,或两者都成功),而glStencilFunc
控制要执行的测试以及哪个参考值(新绘制对象的值)。但是这个例子和链接的文档应该让你开始讨论这个问题。
但仍然要记住,模板缓冲区实际上是用于“即时”图像空间模板操作。如果这变得更加复杂并且您需要对对象执行实际的几何操作,或者如果需要在3D中完成(关键字:Constructive Solid Geometry (CSG)),那么OpenGL不适合作业并且在此案例一个实际的几何库是最好的主意。所有OpenGL都会在屏幕上绘制简单的东西(如点,线或三角形),没有别的。它既不是场景管理,也不是几何,也不是图像处理库(虽然它可能“误用”,后者并不困难)。