对于侧面Android项目,我需要使用带有alpha混合的压缩纹理。 etc2似乎是一个不错的选择,并且应该在OpenGL ES 3+上受支持,但我无法使其正常工作。我觉得自己缺少一些琐碎的东西。
尽管etc1纹理可以很好地工作(但缺少alpha值),但是etc2纹理在我的设备(Mi A1,Android 9)和仿真器上均失败。创建纹理时,GLES30.glCompressedTexImage2D导致错误1281(无效值)。
override fun onSurfaceCreated(gl: GL10, config: EGLConfig) {
val vers = IntArray(2)
GLES30.glGetIntegerv(GLES30.GL_MAJOR_VERSION, vers, 0)
GLES30.glGetIntegerv(GLES30.GL_MINOR_VERSION, vers, 1)
LOG.info("GLES version: ${vers[0]}.${vers[1]}")
if (vers[0] > 3 || vers[0] == 3 && vers[1] >= 1) {
// We have at least ES 3.1.
}
// first, try to generate a texture handle
GLES30.glGenTextures(1, textures, 0)
if (textures[0] == GLES30.GL_FALSE)
throw RuntimeException("Error loading texture")
// bind the texture and set parameters
GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, textures[0])
GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST)
GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_NEAREST)
val resId = R.raw.texture_etc2
//val resId = R.raw.texture_etc1
val texture = ETC2Util.createTexture(context.resources.openRawResource(resId))
LOG.info("compressionFormat: " + texture.compressionFormat + ", capacity: " + texture.data.capacity())
GLES30.glCompressedTexImage2D(GLES30.GL_TEXTURE_2D, 0, texture.compressionFormat, texture.width, texture.height, 0,
texture.data.capacity(), texture.data);
LOG.info("error: " + GLES30.glGetError())
}
尽管GLES版本足够高,但glGetError返回错误1281:
I/TextureRenderer: GLES version: 3.2
D/vndksupport: Loading /vendor/lib64/hw/android.hardware.graphics.mapper@2.0-impl.so from current namespace instead of sphal namespace.
D/vndksupport: Loading /vendor/lib64/hw/gralloc.msm8953.so from current namespace instead of sphal namespace.
I/ETC2Util: width: 128, height: 128, format: 37496, encoded size: 8192
I/TextureRenderer: compressionFormat: 37496, capacity: 8192
error: 1281
请注意,37496等于GLES30.GL_COMPRESSED_RGBA8_ETC2_EAC。
当我使用etc1纹理时,一切运行顺利。 glGetError返回0,并且纹理可以正常使用(当然,“ no alpha”部分除外)。 当我使用etc2纹理时,glGetError返回1281并且纹理保持黑色。
问题似乎不是实际的纹理数据,而是纯粹的internalFormat参数:如果我指定etc1纹理格式(36196、0x8D64,奇怪的是在GLES30中找不到?),但使用etc2数据则未报告错误但由于OpenGL ES试图将etc2数据解释为etc1,所以屏幕上显示了垃圾。
感觉好像只是不支持etc2,但是我发现所有来源都声称etc2在OpenGL ES 3.0和更高版本的Android上是必需的?