Android OpenGL纹理/物体检测
我正在尝试执行 OpenGL 拾取(即回答“在哪个对象上 用户点击了吗?”问题)。 我用谷歌搜索并找到了一些不同的技术,但没有一个适合 我
- 用 glReadPixels 检查像素颜色:我正在使用纹理,所以 它不适合
- 用 glReadPixels 检查像素 alpha:我使用 alpha 混合,因此不适合
- 构建射线并检查碰撞:哎呀!,我宁愿不去 进入那个...
- glRenderMode(GL_SELECT):OpenGL ES不支持
我一直在考虑检查模板缓冲区值。我不 将其用于通常用途,因此我的每个对象都可以写入其 ID 其中(我的对象少于 255 个)。 问题是我无法读取模板缓冲区值 使用 glReadPixels。 RGBA 没问题,但我无法让它适用于 模板值。 这是我的代码:
ByteBuffer bb = ByteBuffer.allocateDirect(4);
bb.order(ByteOrder.nativeOrder());
bb.position(0);
glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, bb);
Log.d(TAG, "color is R"+ bb.get() + " G" + bb.get() + " B" +
bb.get() + " A" + bb.get());
// ---> This is working fine, I can read RGBA correctly
bb.position(0);
glReadPixels(x, y, 1, 1, GL11ExtensionPack.GL_STENCIL_INDEX,
GL_UNSIGNED_BYTE, bb);
Log.d(TAG, "stencil is "+ bb.get());
// ---> This is not working, looks like it isn't doing anything
因为我仍然在缓冲区中获取 R 值...
我确信模板缓冲区已启动并正在运行,因为我设法使用 进行一些剪辑。 使用 setEGLConfigChooser(8, 8, 8, 8, 8, 8) 将其配置为 8 位。
是平台的限制还是我做得不对 方式? (我没有找到任何读取模板缓冲区的实际示例)
此外,任何人都可以建议除了使用模板缓冲区之外是否还有其他方法来检测用户单击的对象 ID?
I'm trying to perform OpenGL picking (i.e. answer the "on which object
did the user click?" question).
I googled it and found a few different techniques, but none is ok for
me
- checking the pixel color with glReadPixels: I'm using textures so
it's not suitable - checking the pixel alpha with glReadPixels: I'm using alpha for
blending so it's not suitable - building a ray and checking collisions: ouch!, i'd prefer to not go
into that... - glRenderMode(GL_SELECT): Not supported in OpenGL ES
I have been thinking about checking the stencil buffer value. I don't
use it for its usual purpose, so each of my objects could write its ID
in it (I have less than 255 objects).
The problem is that I don't manage to read the stencil buffer value
using glReadPixels.
No problem for RGBA, but I don't manage to make it working for the
Stencil value.
Here is my code:
ByteBuffer bb = ByteBuffer.allocateDirect(4);
bb.order(ByteOrder.nativeOrder());
bb.position(0);
glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, bb);
Log.d(TAG, "color is R"+ bb.get() + " G" + bb.get() + " B" +
bb.get() + " A" + bb.get());
// ---> This is working fine, I can read RGBA correctly
bb.position(0);
glReadPixels(x, y, 1, 1, GL11ExtensionPack.GL_STENCIL_INDEX,
GL_UNSIGNED_BYTE, bb);
Log.d(TAG, "stencil is "+ bb.get());
// ---> This is not working, looks like it isn't doing anything
since I still get the R value in the buffer...
I'm sure the stencil buffer is up and running because I managed to use
it for some clipping.
It is configured to 8bits using setEGLConfigChooser(8, 8, 8, 8, 8, 8).
Is it a limitation of the platform or is it me not doing it the right
way? (I didn't find any actual example of reading the stencil buffer)
Also, can anybody suggest if there is any method other than using stencil buffer, to detect the object id on which the user clicks?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
实际上,将光线投射到场景中并检查碰撞是选择的拾取方法。
如果您想使用 glReadPixels 方法,您只需将对象渲染到后台缓冲区(将对象的 ID 编码为常量颜色),而无需交换缓冲区。您仍然可以将对象渲染为完全纹理化以供显示。仅当用户单击(并且场景实际更改)时才用其对象颜色渲染它们,并且仅将它们渲染到后台缓冲区中而不显示它们。
Actually casting a ray into the scene and checking for collisions is the method of choice for picking.
If you want to use the glReadPixels approach, you can just render your objects into the back buffer (with the object's ID encoded as a constant color) without swapping buffers. You can still render your objects fully textured for display. You only render them with their object color when the user has clicked (and the scene actually changed) and only into the back buffer without displaying them.
为什么这不起作用?
您可以使用 glReadPixels 来阅读 SurfaceTexture 像素颜色,无论媒体源是来自相机还是视频文件。
查看 MediaDump 项目,尝试使用 GLSurfaceView 将每个视频帧转储到单个图像文件中,您可以修改它以进行进一步处理或将源更改为相机,两者都是可行的。但请注意 setEGLConfigChooser,它会影响像素读取速度。
Why this doesn't work?
You could use glReadPixels to read the SurfaceTexture pixels color whether the media source is from camera or video file.
Check out the MediaDump project, which trying to dump every video frame into single image files using GLSurfaceView, you could modify it to do further processing or change the source to camera, both are workable. But notice the RGBA sizes setting in the setEGLConfigChooser, it will affect the pixels reading speed.