Android OpenGL 纹理/对象检测

Posted

技术标签:

【中文标题】Android OpenGL 纹理/对象检测【英文标题】:Android OpenGL texture / object detection 【发布时间】:2011-05-20 12:58:38 【问题描述】:

我正在尝试执行 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?

【问题讨论】:

您提到使用射线检测碰撞 - 我认为这将是检测对象交互的最佳方式。如果您想要一些代码示例(高级、非 OpenGL),请查看 Three.js 库的源代码。他们有一个利用光线进行碰撞的实用程序。 github.com/mrdoob/three.js 您已被告知要使用光线拾取。有充分的理由:OpenGL 的唯一目的是在屏幕上显示漂亮的图片。没有对象和场景管理,没有几何操作,没有更高级别的功能。这就是它的全部意义以及应该如何使用它。 您标记了您的问题 rubiks-cube。这意味着您只需要实现光线立方体相交。这是最简单的一种,在 google 上有很多。 【参考方案1】:

实际上将光线投射到场景中并检查碰撞是拾取的首选方法。

如果您想使用 glReadPixels 方法,您只需将对象渲染到后台缓冲区(对象的 ID 编码为常量颜色),而无需交换缓冲区。您仍然可以渲染您的对象完全纹理化以供显示。只有在用户单击(并且场景实际发生变化)时,您才使用对象颜色渲染它们,并且仅在不显示它们的情况下将它们渲染到后台缓冲区。

【讨论】:

【参考方案2】:

使用 glReadPixels 检查像素颜色:我使用的是纹理,所以不适合

为什么这不起作用? 无论媒体源来自相机还是视频文件,您都可以使用glReadPixels 读取SurfaceTexture 像素颜色。

查看MediaDump 项目,该项目尝试使用 GLSurfaceView 将每个视频帧转储到单个图像文件中,您可以对其进行修改以进行进一步处理或将源更改为相机,两者都是可行的。但是请注意setEGLConfigChooser中的RGBA尺寸设置,它会影响pixels reading speed。

【讨论】:

以上是关于Android OpenGL 纹理/对象检测的主要内容,如果未能解决你的问题,请参考以下文章

在OpenGL ES(Android)中使用带纹理的索引缓冲区有什么意义吗?

OpenGL学习脚印:立方体纹理和天空包围盒(Cubemaps And Skybox)

OpenGL:纹理渲染卡住

在android opengl es中检测面向相机的立方体的一侧

Android 上的 OpenGL - 将位图转换为纹理,并保存纹理

Android OpenGL ES----理解纹理与纹理过滤