2013-02-27 57 views
0

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

+0

ES对像素没有实际的逻辑运算。最好的选择似乎是一些模板缓冲技巧。顺便说一句,ES 1或2? – 2013-02-27 12:55:16

+0

@ChristianRau你能提供关于如何做到这一点的任何链接?即时通讯使用Cocos3D为iPhone,它现在不支持ES 2,所以答案是ES 1 – medvedNick 2013-02-27 14:07:28

回答

3

既然你要投射后两个对象的图像空间交集,而不是与球体的立方体的实际几何交集(因为这绝对不是OpenGL是),你可以使用stencilbuffer此:

首先确保你有一个模板缓冲区(取决于你的上下文创建框架,不知道Cocos3D如何做,但OpenGL ES 1本身支持模板测试)。然后做立方体和球体的事情之前,当然使制版,并在帧的开始(与其他缓冲区可能在一起)清除模板缓存:

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

首先我们呈现立方体只有到模板缓冲,为每个绘制的像素递增模板值(开始于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,而立方体和球体像素处处都有一个1

然后,我们只是借鉴的东西都正常,但只有在模板缓存不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_STENCIL_TEST))。

这只是一个基本的例子,但它应该让你开始使用相当强大的模板缓冲区。

目前整个事情都依赖于深度测试结果,这意味着它取决于您绘制对象的顺序。如果您希望它与深度无关(因此只考虑它们的2D屏幕投影) ,则可以在不进行深度测试的情况下绘制对象,也可以将第二个参数glStencilOp(这是在模板测试通过但深度测试失败时执行的操作)设置为GL_INCR

此刻,它也只适用于启用背面剔除的情况,否则模板值会为每个对象增加两次(至少如果忽略深度),并且事情对于非凸对象。也许你也可以使用其他的模板操作来执行你的任务,但不幸的是OpenGL ES 1似乎不支持模板值的二进制操作,也没有包装操作(因此递减0再次为0)。

编辑︰好吧,你真的想要在3D对象之间的几何交叉(或者看起来不同)。那么你的问题不能被OpenGL本身解决。 OpenGL不会做任何事情,然后在屏幕上绘制简单的图元(点,线和三角形)。它既不是一个场景管理系统,也不是一个几何图书馆。你试图实现的是一个不是那么简单的任务(尽管使用像立方体和球体这样简单的对象当然有帮助),你可能需要寻找一些几何库来实现网格布尔操作(或者Constructive Solid Geomtry (CSG)),它可以产生适当的几何差异一个三角网格,然后你可以像往常一样用OpenGL绘制。

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

最终使用合适的CSG库可能是您最好的选择,无论哪种方式,OpenGL都没有任何关系。

+0

感谢您的详细答案,但我认为我问我的问题不够正确......我其实是指几何交叉口,而词“空间”不是用于投影图像,而是用于3D空间。澄清:如果算子不是“立方体xor球体”而是“立方体而不是球体”,应该画出一部分半球形立方体(在3D中)。所以我需要有点像模板缓冲区,不是用于平面图像,而是3D空间。我开始怀疑,如果GL能够自己处理。尽管 – medvedNick 2013-02-27 16:09:01

+0

@medvedNick哦,那么这改变了一切,事实上这个问题并没有被OpenGL完全实现,因为如你所知,OpenGL只是将简单的东西绘制到屏幕上而没有其他东西。 – 2013-02-27 16:30:55