我没有使用2048 x 2048和437kb的大小进行拍摄。但是,当它加载libgdx时,我的内存急剧增加(4mb)。似乎在一般的opengl文件中,类型和压缩不是必需的,而仅仅是在内存中看到位图。
问题在于,一次资产加载程序的数量无误退出时,许多图像都在Android中。
我的游戏具有战略意义,包括墙纸和建筑物以及许多角色。同时根据现场需要,没有交叉装载的可能性。 (像部落冲突的游戏)。
现在的问题是我有多少东西,我将图像加载到内存中以在适用于低内存的Android手机上播放。
最佳答案
这是因为OpenGL以未压缩的图片格式存储图像。可以使用S3TC_DXT纹理压缩算法来压缩内存。要启用它,您只需要在glTexImage2D
调用中指定纹理压缩算法即可。
glTexImage2D(GL_TEXTURE2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, width, height, 0, externalFormat, GL_BYTE);
您还可以检查纹理是否被压缩调用:
int iFlag;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &iFlag);
或通过调用以下命令加载已压缩的DDS纹理:
void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalFormat,
GLsizei width, GLsizei height,
GLint border, GLsizei imageSize, void *data);
下面提供了有关S3纹理压缩(S3TC)的更多信息(摘自https://www.opengl.org/wiki/S3_Texture_Compression):
S3TC是一种压缩图像以用作纹理的技术。像JPEG和PNG这样的标准图像压缩技术可以实现比S3TC更高的压缩率。但是,S3TC被设计为在高性能硬件中实现。 JPEG和PNG一次全部解压缩图像,而S3TC允许独立地解压缩图像的特定部分。
S3TC是基于块的格式。图像分为4x4块。对于大小不是4的倍数的非2的幂的图像,将4x4块的其他颜色视为黑色。每个4x4块彼此独立,因此可以独立进行解压缩。
OpenGL接受3种形式的S3TC。这些格式以以下格式的旧Direct3D名称命名:DXT1,DXT3和DXT5。
DXT1格式
DXT1压缩的图像是RGB图像格式。这样,任何颜色的alpha都假定为1。每个4x4块占用64位数据,因此与24位RGB格式相比,它提供6:1压缩。您可以使用
GL_COMPRESSED_RGB_S3TC_DXT1_EXT
作为图像的内部格式来获取DXT1图像。每个4x4块按如下方式存储颜色数据。有2个16位颜色值,color0后跟color1。其后是一个32位无符号整数,该整数包含描述两种颜色如何组合以确定给定像素的颜色的值。
2个16位颜色值以Little-endian格式存储,因此16位颜色的低字节在每种情况下都排在首位。颜色值以
5_6_5
位的RGB顺序(从高位到低位)存储。32位无符号整数也以little-endian格式存储。整数的每2位代表一个像素;这两位是定义如何将color0和color1组合以产生该像素颜色的代码。按照从最高位到最低位的顺序(在小端顺序转换之后),像素按行优先顺序存储。每8位(4个2位代码)是图像的一行。
这是设置图:
63 55 47 39 31 23 15 7 0
| c0-low | c0-hi | c1-low | c1-hi | codes0 | codes1 | codes2 | codes3 |
-------------------------------------------------------------------------
c0-low是16位颜色0的低字节;类似地,c0-hi是颜色0的高字节。要重构颜色0,只需执行以下操作:
((bytes[1] << 8) + bytes[0])
,其中bytes是包含上述字节序列的数组。颜色1来自((bytes[3] << 8) + bytes[2])
。同样,这些代码是组成32位整数位代码的字节。它们必须以相反的顺序重建,因此code3是最左边的字节。
重建为正确的顺序后,您可以像这样获得单个的2位值。像素值采用cXY形式,其中Y按照OpenGL的标准从下到上排列:
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
| c00 | c10 | c20 | c30 | c01 | c11 | c21 | c31 | c02 | c12 | c22 | c32 | c03 | c13 | c23 | c33
| codes3 | codes2 | codes1 | codes0
------------------------------------------------------------------------------------------------
2位值的解释取决于color0和color1相互比较的方式。如果color0的整数值大于color1,则2位值的含义与color0小于或等于color1的含义有所不同。 2位值的含义如下:
code | color0 > color1 | color0 <= color1
----------------------------------------------------
0 | color0 | color0
1 | color1 | color1
2 | (2*color0 + color1) / 3 | (color0 + color1) / 2
3 | (color0 + 2*color1) / 3 | Black
算术运算是按分量完成的,而不是颜色的整数值。而值“Black”仅是R = G = B = 0。
带有1位Alpha的DXT1
DXT1有一种形式,可提供简单的开/关alpha值。因此,此格式使用RGBA基本格式。要获得此格式,请使用
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
内部格式。数据格式与上述情况相同,这就是为什么它仍是DXT1压缩的原因。解释略有不同。除非像素使用上表中的“黑色”代码,否则您始终将alpha值设为1。在这种情况下,您获得的alpha值为0。
请注意,这意味着在任何具有0 alpha的像素上,RGB颜色也将为0。这也意味着相邻纹理像素之间的双线性滤波将导致颜色与黑色结合。如果您正在使用预乘alpha混合,这就是您想要的。如果不是,那么几乎可以肯定不是您想要的。
当使用OpenGL压缩纹理时,GL实现将假定alpha值<0.5的任何像素的alpha均应为0。这是手动压缩图像的另一个原因。
DXT3格式
DXT3格式是RGBA格式。每个4x4块占用128位数据。因此,与32位RGBA纹理相比,它提供4:1压缩。您可以使用
GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
内部格式来获取它。每个128位块分为2个64位块。第二个块包含颜色信息,几乎像在DXT1情况下一样进行了压缩;在确定如何使用代码提取颜色值方面,始终假定color0小于color1。第一块包含Alpha信息。
alpha 64位块存储为Little-endian 64位无符号整数。 Alpha值存储为每像素4位的Alpha值。从64位无符号整数的最高位开始,按行优先顺序存储alpha值。
DXT5格式
DXT5格式是另一种RGBA格式。与DXT3情况一样,每个4x4块占用128位。因此,它提供与DXT3情况相同的4:1压缩。您可以使用
GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
格式来获取它。就像DXT3格式一样,每个块有两个64位数据块:一个与DXT1压缩的RGB块(与DXT3相同的警告)和一个alpha块。同样,第二个块是颜色块;第一个是Alpha。
DXT3和DXT5的不同之处在于alpha块的压缩方式。 DXT5使用类似于DXT1的压缩方案压缩alpha。
alpha数据存储为2个8位alpha值alpha0和alpha1,后跟一个48位无符号整数,该整数描述了如何组合这两个参考alpha值以获得最终的alpha值。 48位整数也按小端顺序存储。
48位无符号整数包含描述如何计算最终alpha值的3位代码。这些代码的存储顺序与DXT1中的代码相同。它们只是3位而不是2位。
就像在DXT1情况下一样,这些代码具有不同的含义,具体取决于alpha0和alpha1相互比较的方式。这是代码和计算表:
code | alpha0 > alpha1 | alpha0 <= alpha1
---------------------------------------------
0 |alpha0 | alpha0
1 |alpha1 | alpha1
2 |(6*alpha0 + 1*alpha1)/7 | (4*alpha0 + 1*alpha1)/5
3 |(5*alpha0 + 2*alpha1)/7 | (3*alpha0 + 2*alpha1)/5
4 |(4*alpha0 + 3*alpha1)/7 | (2*alpha0 + 3*alpha1)/5
5 |(3*alpha0 + 4*alpha1)/7 | (1*alpha0 + 4*alpha1)/5
6 |(2*alpha0 + 5*alpha1)/7 | 0.0
7 |(1*alpha0 + 6*alpha1)/7 | 1.0
有关更多信息,请访问S3 Texture Compression
还有更多现代的纹理压缩算法
对于OpenGL 4.2 OpenGL-ES 3.0 Ericsson Texture Compression (ETC):
GL_COMPRESSED_RGB8_ETC2
GL_COMPRESSED_SRGB8_ETC2
GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
GL_COMPRESSED_RGBA8_ETC2_EAC
GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
GL_COMPRESSED_R11_EAC
GL_COMPRESSED_SIGNED_R11_EAC
GL_COMPRESSED_RG11_EAC
GL_COMPRESSED_SIGNED_RG11_EAC
还有 Adaptive Scalable Texture Compression 。
关于image - 为什么您看到内存中加载的图像大小(在libgdx中)占用了您自己的更多照片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35356746/