对于侧面Android项目,我需要使用带有alpha混合的压缩纹理。 etc2似乎是一个不错的选择,应该在OpenGL ES 3+上得到支持,但我无法让它们工作。 我觉得我错过了一些微不足道的东西。
虽然etc1纹理效果很好(但缺少alpha),但是et2纹理在我的设备(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支持在Android上的OpenGL ES 3.0及更高版本上是强制性的?