我在OpenGL2.0中制作游戏并且我想检查两个精灵是否有交集,但我不需要检查两个矩形之间的交叉点。我有两个带纹理的精灵,一些纹理的一部分是透明的,有些则不是。我需要检查sprite之间的交集仅在不透明的部分。
答案 0 :(得分:0)
确定两个精灵之间交集的最简单方法是使用Bounding Box方法。
对象1边界框:
vec3 min1 = {Xmin, Ymin, Zmin}
vec3 max1 = {Xmax, Ymax, Zmax}
对象2边界框:
vec3 min2 = {Xmin, Ymin, Zmin}
vec3 max2 = {Xmax, Ymax, Zmax}
您必须通过遍历精灵的顶点缓冲区数组来预先计算边界框。 http://en.wikibooks.org/wiki/OpenGL_Programming/Bounding_box
然后在每个渲染帧期间检查边界框是否重叠(在CPU上计算)。
a)首先转换Mins&最大的世界空间。
min1WorldSpace = modelViewMatrix * min1
b)然后检查它们的重叠。
我需要检查精灵之间的交叉点,而不仅仅是在没有透明的部分。
根据您的场景,检查此测试用例可能很复杂。您可能必须将透明精灵分割为单独的精灵并计算其边界框。
在您的示例中,透明对象看起来像是封装在不透明对象内部,因此很容易。只需计算两个边界框。
答案 1 :(得分:0)
我不认为使用ES 2.0有一种非常优雅的方式。 ES 2.0是OpenGL的一个非常小的版本,你开始突破它可以做的事情的界限。例如,在ES 3.0中,您可以使用查询,这对于很好地有效地解决这个问题非常有帮助。
在ES 2.0中可以做的是以某种方式绘制精灵,以便只有两个交叉点中的像素最终产生颜色。这可以通过使用模板缓冲区或混合来实现(请参阅下面的详细信息)。但是你需要找出是否有任何像素被渲染,并且ES 2.0中没有任何好的机制我可以想到这样做。我相信你几乎坚持使用glReadPixels()
读取结果,然后检查CPU上的非黑色像素。
我必须避免回读整个图像的一个想法是反复下采样直到它达到1x1的大小。它最初将渲染到纹理,然后在每个步骤中,使用线性采样对当前纹理进行采样,渲染为一半大小的纹理。我相信这会有效,但我不确定它是否比回读整个图像更有效。
我不会提供建议解决方案的完整代码,但大纲如下所示。这是使用混合仅绘制交叉点中的像素。
渲染第一个只有alpha输出的sprite,而不是混合。
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
glDisable(GL_BLEND);
// draw sprite 1
这将精灵1的alpha值保留在帧缓冲区的alpha中。
使用目标alpha混合渲染第二个精灵。透明像素的RGB组件需要有黑色才能正常工作。如果不是这种情况,请更改片段着色器以创建预乘的颜色(将rgb
输出乘以a
。)
glColorMask(GL_TRUE GL_TRUE, GL_TRUE, GL_TRUE);
glBlendFunc(GL_DST_ALPHA, GL_ZERO);
glEnable(GL_BLEND);
// draw sprite 2
只有精灵1的alpha值非零时,才会使精灵2呈现颜色输出。
glReadPixels()
回读结果。被读取的区域至少需要覆盖两个精灵的边界框。