Opengl es 用于绘图的OpenGL ES xor模式

Opengl es 用于绘图的OpenGL ES xor模式,opengl-es,Opengl Es,OpenGL ES是否具有XOR绘图模式?我想在该模式下绘制一个立方体,然后绘制一个与立方体相交的球体,输出应该是立方体的一部分和球体的一部分,但相交为空。假设您希望投影后两个对象的图像空间相交,而不是立方体与球体的实际几何相交(因为这绝对不是OpenGL的用途),您可以使用: 首先确保您有一个模具缓冲区(取决于您的上下文创建框架,不知道Cocos3D是如何做到的,但OpenGL ES 1本身支持模具测试)。然后当然在执行立方体和球体操作之前启用模具,并在帧开始时清除模具缓冲区(可能与其他缓冲区

OpenGL ES是否具有XOR绘图模式?我想在该模式下绘制一个立方体,然后绘制一个与立方体相交的球体,输出应该是立方体的一部分和球体的一部分,但相交为空。

假设您希望投影后两个对象的图像空间相交,而不是立方体与球体的实际几何相交(因为这绝对不是OpenGL的用途),您可以使用:

首先确保您有一个模具缓冲区(取决于您的上下文创建框架,不知道Cocos3D是如何做到的,但OpenGL ES 1本身支持模具测试)。然后当然在执行立方体和球体操作之前启用模具,并在帧开始时清除模具缓冲区(可能与其他缓冲区一起):

首先,我们只将立方体渲染到模具缓冲区中,增加每个绘制像素的模具值(从
0
开始)

glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); //don't really draw anything
glStencilFunc(GL_ALWAYS, 0, -1);    //always pass the test (default anyway)
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);  //increment for each drawn pixel
//draw object
然后我们对球体执行相同的操作。之后,模具缓冲区在立方体像素或球体像素的每一处都有一个
1
,在立方体和球体像素的每一处都有一个
2

然后我们正常地绘制这两个对象,但仅在模具缓冲区不是
2
(或者如果需要,在
1
的位置)的情况下绘制,因此我们不在交叉点绘制任何对象:

glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);  //draw something
glStencilFunc(GL_NOTEQUAL, 2, -1);      //draw everywhere except at intersection
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);    //leave the stencil buffer as is
//draw cube
//draw sphere
最后,完成后,我们再次禁用模具测试(
glDisable(GL\u模具测试)

这只是一个基本的例子,但它应该让您开始使用非常强大的模具缓冲区

目前,整个过程取决于深度测试结果,这意味着它取决于您绘制对象的顺序。如果您希望它独立于深度(因此仅考虑其二维屏幕投影),则您可以在不进行深度测试的情况下绘制对象,或设置
glStencilOp
(这是当模具测试通过但深度测试失败时执行的操作)到
GL_INCR

目前,它也仅在启用背面消隐时有效,因为否则每个对象的模具值将增加两次(至少在忽略深度的情况下),对于非凸面对象,情况会更糟。也许您也可以使用其他模具操作来执行任务,但不幸的是,OpenGL ES 1似乎不支持模具值的二进制操作,也不支持包装操作(因此,递减
0
又是
0

编辑:好的,你真的想要3D对象之间的几何交点(或者说看起来的差异)。那么你的问题不是OpenGL自己能解决的。OpenGL不做任何其他事情,然后画简单的原语(点、线和三角形)它既不是一个场景管理系统,也不是一个几何体库。您试图实现的任务并不那么简单(尽管使用立方体和球体等简单对象肯定会有所帮助),您可能需要寻找一些几何体库,用于网格上的布尔运算(或)这将生成适当的几何差异,作为三角形网格,然后可以像往常一样使用OpenGL绘制

另一个类似于您提到的“3D模具缓冲区”概念的选项是使用规则网格离散空间,从而将对象细分为小体素(3D像素,想想小方框)。在这些离散有限体素集上,布尔运算非常容易。但当然,这种方法的代价是引入离散化错误和性能开销(在体素上操作意味着在大数据集上操作,ok CSG也不容易,但可能比O(n^3)更复杂)。您还必须再次从体素集中重新创建可渲染对象,或者使用某些曲面提取方法再次获取网格,或者仅绘制小点或长方体


最后,使用合适的CSG库可能是你的最佳选择,无论哪种方式,OpenGL都与之无关。

假设你希望投影后两个对象的图像空间相交,而不是立方体与球体的实际几何相交(因为这绝对不是OpenGL的目的),您可以为此使用:

首先确保您有一个模具缓冲区(取决于您的上下文创建框架,不知道Cocos3D是如何做到的,但OpenGL ES 1本身支持模具测试)。然后当然在执行立方体和球体操作之前启用模具,并在帧开始时清除模具缓冲区(可能与其他缓冲区一起):

首先,我们只将立方体渲染到模具缓冲区中,增加每个绘制像素的模具值(从
0
开始)

glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); //don't really draw anything
glStencilFunc(GL_ALWAYS, 0, -1);    //always pass the test (default anyway)
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);  //increment for each drawn pixel
//draw object
然后我们对球体执行相同的操作。之后,模具缓冲区在立方体像素或球体像素的每一处都有一个
1
,在立方体和球体像素的每一处都有一个
2

然后我们正常地绘制这两个对象,但仅在模具缓冲区不是
2
(或者如果需要,在
1
的位置)的情况下绘制,因此我们不在交叉点绘制任何对象:

glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);  //draw something
glStencilFunc(GL_NOTEQUAL, 2, -1);      //draw everywhere except at intersection
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);    //leave the stencil buffer as is
//draw cube
//draw sphere
最后,完成后,我们再次禁用模具测试(
glDisable(GL\u模具测试)

这只是一个基本的例子,但它应该让您开始使用非常强大的模具缓冲区

目前,整个过程取决于深度测试结果,这意味着它取决于您绘制对象的顺序。如果您希望它独立于深度(因此仅考虑其二维屏幕投影),则您可以在不进行深度测试的情况下绘制对象,或设置
glStencilOp
(这是当模具测试通过但深度测试失败时执行的操作)到
GL_INCR

目前,它也仅在启用背面剔除的情况下起作用,否则ste