【问题标题】:Converting from GLSurfaceView to TextureView (via GLTextureView)从 GLSurfaceView 转换为 TextureView(通过 GLTextureView)
【发布时间】:2012-08-21 19:08:05
【问题描述】:

Android 4.0 (Ice Cream Sandwich) 发布时,在 sdk 中引入了一个新视图。这个 View 就是 TextureView。在文档中,它说 TextureView 可用于显示 OpenGL 场景的内容。

当您查看如何执行此操作时,您会发现此链接指向一个示例。

https://groups.google.com/forum/?fromgroups=#!topic/android-developers/U5RXFGpAHPE

但是,我只想将 GLSurfaceView 替换为 TextureView,并保持我的其余代码相同,并获得 TextureView 的优势。

【问题讨论】:

标签: android opengl-es google-tv


【解决方案1】:

答案:

1) 从GLSurfaceView的源代码开始,将文件命名为GLTextureView.java

2) 将标题更改为: GLTextureView 扩展 TextureView 实现 SurfaceTextureListener

3) 将构造函数重命名为 GLTextureView。从 init() 方法中删除代码。

4) 组织导入。始终选择非 GLSurfaceView 选项。

5) 找到 SurfaceHolder 的每个实例并将其更改为 SurfaceTexture

6) 为SurfaceTextureListener添加未实现的方法,每个方法应该如下:

  • onSurfaceTextureAvailable - surfaceCreated(surface)
  • onSurfaceTextureDestroyed - surfaceDestroyed(surface), (return true)
  • onSurfaceTextureSizeChanged - surfaceChanged(surface, 0, width, height)
  • onSurfaceTextureUpdated - requestRender()

7) 应该有一行调用 getHolder(),将其更改为 getSurfaceTexture()

8) 在 init() 方法中,放入以下行 setSurfaceTextureListener(this)

然后添加一个OnLayoutChangeListener 并让它调用surfaceChanged(getSurfaceTexture(), 0, right - left, bottom - top)

这样,您应该能够将您的 GLSurfaceView 代码替换为 GLTextureView 并获得 GLTextureView 的好处。还要确保您的应用支持硬件加速并且您的渲染器扩展了GLTextureView.Renderer。

【讨论】:

  • 添加到 Robin 和 William 的答案:当您想要将 SurfaceView 转换为 TextureView 时,此方法适用于所有情况。
  • 可以发布一个这样的例子吗?我发现了这个:github.com/eaglesakura/gltextureview/blob/master/GLTextureView/… 这和你描述的方法相似吗?
  • 请注意,虽然这个答案确实有效,但您不想执行第 5 点的最后一步,即onSurfaceTextureUpdated - requestRender()。使用这一行,即使渲染模式设置为 RENDERMODE_WHEN_DIRTY,也会连续调用 onDrawFrame。没有它,RENDERMODE_WHEN_DIRTY 会正常运行。
  • @William Goodalte 你能看看这个帖子吗? stackoverflow.com/questions/32482565/…
  • 在某些 Android 版本上,这将尽可能快地绘制 -- >1000fps!要限制帧率,请使用 RENDERMODE_DIRTY 并使用 Choreographer 调用 requestRender()。
【解决方案2】:

太棒了!

Goodale 先生精彩回答的一个小补充:

我认为,GLSurfaceView 的 4.1.1 版本似乎已经过修改,以避免在零宽度/高度表面上进行渲染。而且似乎没有在 onSurfaceTextureAvailable 之后立即出现无偿的 onSurfaceTextureChanged 通知。

如果从 4.1.1 的源开始,onSurfaceTextureAvailable 需要如下所示:

public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
        int height) 
{
    this.surfaceCreated(surface);
    this.surfaceChanged(surface, 0,width,height);
}

除此之外,我在大约五分钟内就启动并运行了!谢谢。

【讨论】:

    【解决方案3】:

    感谢 Goodale 先生和 Davies 先生的解答!

    我有一些关于将 GLSurfaceView 转换为 GLTextureView 的额外信息。 首先是关于渲染模式。 如there 所述,只需删除 onSurfaceTextureUpdated 中的 requestRender() 调用即可。

    第二个是关于
    mGLESVersion = SystemProperties.getInt("ro.opengles.version", ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 就用link,但是你需要Context来做context.getClassLoader(); 您可以从 init() 调用 getInt 的反射版本并将结果保存在静态字段中 sGLESVersion = getInt(getContext(), "ro.opengles.version",ConfigurationInfo.GL_ES_VERSION_UNDEFINED);

    最后一个最简单的更改是关于 EGLLogWrapper.getErrorString(error); 只需从 EGLLogWrapper 源复制 getErrorString。

    GitHub Gist上查看我将 GLSurfaceView 转换为 GLTextureView 的最终版本

    【讨论】:

    • 我在 Android 5.0 上试过这个(compileSdkVersion 21)。如果我试图让 GLTextureView 透明,这会崩溃——我打电话给setEGLConfigChooser(8, 8, 8, 8, 16, 0); and setOpaque(false)。我应该在 gradle 中使用任何特定的 compileSdkVersion 试试你的要点吗?
    • 值得注意的是,您可以通过以下方式在没有反射的情况下执行此操作:final ActivityManager activityManager = (ActivityManager) c.getSystemService(Context.ACTIVITY_SERVICE); final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo(); sGLESVersion = configurationInfo.reqGlEsVersion;
    • 我认为这只是因为找不到配置。试试 setEGLConfigChooser(8, 8, 8, 8, 24, 0);
    【解决方案4】:

    如果你想复制/粘贴一个现成的类,我在这里写了一个:

    GLTextureView

    您可以调用 setRenderer(GLSurfaceView.Renderer),就像使用 GLSurfaceView。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-13
      • 1970-01-01
      • 1970-01-01
      • 2017-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多