我正在尝试通过压缩纹理来优化我的应用。由于我的很多纹理需要alpha,我不能使用ETC1。
我已经使用这篇文章中的提示成功地将纹理压缩为其他格式。 Android OpenGL Texture Compression
问题是我似乎无法调整我的代码,阅读这个纹理。我用这段代码唯一得到的是黑色(颜色,而不是纹理)。
这是加载纹理的方法:
public static int loadCompressedTexture(Context context, int resourceId){
final int[] textureObjectIds = new int[1];
glGenTextures(1, textureObjectIds, 0);
if(textureObjectIds[0] == 0){
logTextureHelper(Log.WARN, "Could not generate a new OpenGL texture object");
return 0;
}
final InputStream bitmap = context.getResources().openRawResource(resourceId);
byte[] buffer;
ByteBuffer bf;
try {
buffer = new byte[bitmap.available()];
bitmap.read(buffer);
bf = ByteBuffer.wrap(buffer);
glBindTexture(GL_TEXTURE_2D, textureObjectIds[0]);//binds texture to texture object
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);//minimization filter
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);//send texture data to OpenGL to the CURRENTLY BOUND object
GLES20.glCompressedTexImage2D(GLES20.GL_TEXTURE_2D, 0, GL10.GL_PALETTE4_RGBA8_OES, 512, 512, 0, bf.capacity(), bf);
//glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0); //unbind texture
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return textureObjectIds[0];
}
我目前正在尝试使用PVRTC 4bpp RGBA编码加载使用PvrTexTool压缩的512x512px资源。
有人能看出问题所在吗?或者更好的是,请指出一个有效的例子?从我发现的我只能找到ETC1的例子,他们使用一些ETCUtil来加载纹理。
EDIT2:好的,我已经解决了。 有2个问题。首先,您需要使用这些纹理过滤器。
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_NEAREST); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR);
其次我不知道pvrtc有一个单独的标题。因此,正确的偏移量为67个字节。 PVRTC format specification
此代码现在可以正常运行:
buffer = new byte[bitmap.available()];
bitmap.read(buffer);
int offset = 67; // 52 bit = header, 15 bit = metadata
bf = ByteBuffer.wrap(buffer, offset, buffer.length-offset);
bf.order(ByteOrder.LITTLE_ENDIAN);
long version = bf.getInt(0) & 0xFFFFFFFFL;
long flags = bf.getInt(4);
long pixelFormat = bf.getLong(8);
long colorF = bf.getInt(16);
long chanel = bf.getInt(20);
int height = bf.getInt(24);
int width = bf.getInt(28);
long depth = bf.getInt(32);
long nsurf = bf.getInt(36);
long nface = bf.getInt(40);
long mipC = bf.getInt(44);
long mSize = bf.getInt(48);
long fourCC = bf.getInt(52)& 0xFFFFFFFFL;
long key = bf.getInt(56)& 0xFFFFFFFFL;
long dataSize = bf.getInt(60)& 0xFFFFFFFFL;
// Log.d("TextureHelper","Buffer size: "+version+" "+flags+" "+pixelFormat+" "+colorF+" "+chanel+" "+height+" w: "+width+" h: "+height+" "+depth+" "+nsurf+" "+nface+" "+mipC+" "+mSize);
// Log.d("TextureHelper","Buffer size: "+fourCC+" "+key+" "+dataSize);
glBindTexture(GL_TEXTURE_2D, textureObjectIds[0]);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glCompressedTexImage2D(GL_TEXTURE_2D, 0,GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, width, height, 0, bf.capacity()-offset, bf);
Log.d("TextureHelper","Buffer size: "+bf.capacity()+" : "+buffer.length+" error:"+GLES20.glGetError());
glBindTexture(GL_TEXTURE_2D, 0); //unbind texture
答案 0 :(得分:2)
您想通过glCompressedTexImage2D加载PVRTC 4bpp RGBA纹理吗?您应该使用COMPRESSED_RGBA_PVRTC_4BPPV1_IMG而不是GL10.GL_PALETTE4_RGBA8_OES。
IMG_texture_compression_pvrtc https://www.khronos.org/registry/gles/extensions/IMG/IMG_texture_compression_pvrtc.txt
我不确定,但似乎Android GLES20没有这些常量,所以你需要定义它。
// PowerVR Texture compression constants
public static final int GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8C00;
public static final int GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG = 0x8C01;
public static final int GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8C02;
public static final int GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG = 0x8C03;
你应该在glCompressedTexImage2D调用后检查glGetError。 glGetError的值应为GL_NO_ERROR。