Как сократить физический размер ресурсов
Обычно больше всего места занимают текстуры. Мы использовали до этого исключительно PNG, а он достаточно много весит. Распространенный хак состоит в том, чтобы разделить PNG на два JPG’a или на JPG + PNG, в первом файле будут храниться RGB каналы, а во втором только маска. Это позволит сильно уменьшит физический размер файлов (у нас вышло более чем в 2 раза, при качестве JPEG = 95).
Для разбиения текстур из PNG на два JPG я написал небольшой скриптик на python’e, который кладет рядом два файла.jpg_alpha.jpg, а оригинальный.png удаляет:
#!/usr/bin/python
import os, fnmatch
import Image
import argparse
import ntpath
import ImageFile
ImageFile.MAXBLOCK = 2048*2048# default is 64k
def splitImage(filename):
print 'splitting %s\n' % png
originalImage = Image.open(filename)
baseName = ntpath.splitext(filename)[0]
originalImage.save(baseName + '.jpg', 'JPEG', quality=95, optimize = True)
if len(originalImage.getbands()) == 4:
ir, ig, ib, ia = originalImage.split()
alphaImage = Image.merge("RGB", (ia, ia, ia));
alphaImage.save(baseName + '_alpha.jpg', 'JPEG', quality=90)
os.remove(filename)
def locate(pattern, root=os.curdir):
for path, dirs, files in os.walk(os.path.abspath(root)):
for filename in fnmatch.filter(files, pattern):
yield os.path.join(path, filename)
parser = argparse.ArgumentParser(description='Pack animations.')
parser.add_argument('images', metavar='I', help='Directory with images')
args = parser.parse_args()
pngDir = args.images
for png in locate("*.png", pngDir):
splitImage(png)
Что касается OpenGL, то в итоге происходит загрузка той же RGBA текстуры, только она собирается из двух файлов. Я беру массив пикселей первой текстуры, записываю их в результирующий массив, а любой из каналов второй текстуры (альфы) я записываю в 4 компонент результирующего массива.