在 OpenGL ES 2.0 中保留源和目标中的最大值(按位或)
让我稍微解释一下标题。在帧缓冲区中,我有一些颜色值(为了简单起见,我将仅引用二进制中的一个颜色通道,例如特定像素中的 00000001)。然后我将在该特定值中写入一个新值。 OpenGL 应检查传入值和该像素中已存在的值,并保留两者的最大值。换句话说,我希望它在传入值和现有值之间执行按位或。因此,如果现有值为 00000001 并且传入值为 00000010,则结果必须为 00000011。
在 OpenGL ES 1.1 中,我认为使用 glLogicOp 可以轻松实现这一点(http://www.opengl.org/sdk/docs/man/ xhtml/glLogicOp.xml) 函数。但这在 OpenGL ES 2.0 中不受支持(为什么为什么他们删除它?:( ),而且我想不出可以实现类似结果的混合函数(我认为使用混合是不可能的)。我应该使用模板缓冲区或其他技巧以实现我的目标吗?
您能描述一下步骤吗?
PS我知道使用着色器一切皆有可能,但这需要付出巨大的努力才能实现,如果这是唯一的解决方案,请给我指示。为了这 。
提前致谢
let me explain the title a little. In the framebuffer I have some color values (for simplicity I am going to refer only to one color channel in binary e.g. 00000001 in a specific pixel). Then in that specific value I am going to write a new value. The OpenGL should examine the incoming value and the value that already exists in that pixel and keep the max of both. In other words I want it to perform a BITWISE OR between the incoming and the existing value. So, if the existing value is 00000001 and the incoming is 00000010 then the result must be 00000011.
In OpenGL ES 1.1 I think this was easily achieved using the glLogicOp (http://www.opengl.org/sdk/docs/man/xhtml/glLogicOp.xml) function. But this is NOT supported in OpenGL ES 2.0 (WHY WHY WHY they removed it?? :( ), and I cannot think of a blending function that can achieve a similar result (I think this is impossible using blending). Should I use the stencil buffer or another trick in order to achieve my goal?
Can you describe the steps for it?
P.S. I know everything is possible using shaders but this will require a huge effort to implement now. If it is the only solution then please give me directions for this approach.
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为你必须为此使用着色器。
1) 创建两个 renderTargets[2],用于与 swapIndex 进行交换。
2) 渲染到一个 renderTarget[swapIndex] 并使用另一个 renderTarget[1-swapIndex] 作为参考纹理,您将从 GLSL 着色器中采样。
3) 在片段(又名像素)着色器中,您将从纹理(又名 renderTarget[1-swapIndex])中采样并将“gl_FragColor”设置为 max(texture, someColor)。
4) 翻转 swapIndex {swapIndex = 1-swapIndex;} 并重新开始。
I think your going to have to use a shader for that.
1) Create two renderTargets[2] that will be used for swapping with a swapIndex.
2) Render to one renderTarget[swapIndex] and use the other renderTarget[1-swapIndex] as a reference texture that you will sample from in you GLSL shader.
3) In the fragment(aka pixel) shader you would sample from your texture(aka renderTarget[1-swapIndex]) and set "gl_FragColor" to max(texture, someColor).
4) Flip the swapIndex {swapIndex = 1-swapIndex;} and start over.
我必须承认我的问题不太清楚。无论如何,我会在这里完善问题并提出解决方案。
我有许多不同类型的任意形状(用户可以创建任意数量的形状并疯狂地使它们变形),我想开发一种方法来从屏幕上像素的颜色检测用户选择了多少形状(用户刚刚触及该像素)。
因此,我使用某种颜色 ID 对形状进行颜色编码。我在二进制级别工作:
屏幕上的第一个形状的颜色 ID 为 00000001,第二个形状的颜色 ID 为 00000010,依此类推。因此,使用一个字节(比如说在红色通道中)我可以存储最多 8 个不同的颜色 ID。如果我使用 RGBA8888 格式,形状的最大数量为 32。
我最初开发的算法是使用 glBlendFunc(GL_ONE, GL_ONE) 在源颜色 id 和目标颜色 id 之间进行混合,一切似乎都工作正常。因此,如果触摸的像素颜色为 00010101,则意味着第一个、第三个和第五个形状被触摸。但是,用户可以创建一些非凸形状(如果这是折叠形状的正确词)。在这种情况下,如果用户折叠颜色 id 为 00000001 的形状,则重叠像素将获得 id 00000010,因为该形状首次在帧缓冲区上绘制时会写入 00000001,然后同一形状的重叠像素会添加另一个 00000001。到混合。
因此,如果以某种方式我可以在帧缓冲区中写入的颜色 ID 之间进行按位或(不符合我最初在问题中提到的逻辑),那么问题就可以解决。事实上,OpenGL ES 1.1 就是这种情况,通过使用 glLogicOp(GL_OR) 函数。不幸的是,这在 OpenGL ES 2.0 上不可用,并且必须再次创建一个着色器、一个通道等,我认为这是矫枉过正且难以维护。
OpenGL ES 2.0 的解决方案是这样的:
最好的
I must admit I was not so clear in my question. Anyway, I will refine the problem and present a resolution to it here.
I have many different kind of arbitrary shapes (the user can create as many of them he wants and crazily deform them) and I want to develop a method to detect from the color of a pixel on the screen how many of the shapes the user picked (the user has just touched on that pixel).
So, I color code the shapes with let's say some kind of color ids. I work in the binary level:
the first shape on the screen has color id 00000001 the second shape has id 00000010 and so on. So, with a byte (in the red channel let's say) I can store up to 8 different color ids. The max number of shapes is 32 if I use an RGBA8888 format.
The algorithm that I initially developed was doing blending between the source color id and the destination color id with a glBlendFunc(GL_ONE, GL_ONE), and everything seemed to work fine. So if a touched pixel with color 00010101, then it meant that the first, third and fifth shapes were touched. BUT, there are some non-convex shapes (if this is the right word for folding shapes) that can be created by the user. In this case if the shape with color id 00000001 is folded by the user then the overlapping pixels will get id 00000010, because the shape writes 00000001 when it is first drawn on the framebuffer and then the overlapping pixels of the same shape add another 00000001 due to blending.
So, if in some way I could do a BITWISE OR (NOT logical as I initially mentioned in my question) between the color ids that were written in the framebuffer then the problem would be solved. Indeed this is the case with OpenGL ES 1.1, by using the glLogicOp(GL_OR) function. UNFORTUNATELY this is not available on OpenGL ES 2.0 and again one shader, one more pass etc must be created which I think is overkill and difficult to maintain.
The solution for OpenGL ES 2.0 is this:
Best
@Summon,抱歉,如果我添加额外的答案而不是评论,我没有足够的声誉来发表评论。
无论如何:
第 1 点:我确信你 100% 不能在着色器中执行按位或/和/移位,因为上个月我不得不为了这个疏忽而浪费了大约两周的编程时间。 :) :)
第2点:看看维基百科上关于GLSL的这篇文章(运算符部分):
1.30版本中添加了按位运算符。
答:如果您尝试将 #version 130 添加到着色器,它们将无法编译。
B. 如果您尝试添加按位运算,例如 A & B(注意单个 &),A | B、A<< 2、B>> 2等等,它不会编译。
在不同的书籍/论坛/SDK 上阅读,我发现了相同的确认。
我希望能够避免我在这件事上遇到的同样令人头疼的问题。
毛里齐奥·贝内代蒂
@Summon, sorry if I add an additional answer instead of a comment, I don't have enough reputation to leave comments.
Anyway:
Point 1: I am sure 100% you cannot perform bitwise or/and/shift in shaders since I had to trash about 2 weeks of programming for this oversight just last month. :) :)
Point 2: Look at this article on wikipedia about GLSL (section Operators):
Bitwise operators were added in version 1.30.
A. If you try to add #version 130 to your shader, they won't compile.
B. If you try to add a bitwise operation such as A & B (notice the single &), A | B, A << 2, B >> 2 etc, it won't compile.
Reading around, on different books/forums/SDK, I have found the same confirmation.
I hope to have avoided the same headache I have had on this matter.
Maurizio Benedetti