Mercurial > touhou
diff pytouhou/ui/texture.pyx @ 426:5d7bb2fd74f7
Never keep texture on the host when it has been uploaded, and prevent them from being decoded again.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Tue, 16 Jul 2013 21:11:35 +0200 |
parents | d8630c086926 |
children | 40d5f3083ebc |
line wrap: on
line diff
--- a/pytouhou/ui/texture.pyx +++ b/pytouhou/ui/texture.pyx @@ -16,7 +16,8 @@ from pytouhou.lib.opengl cimport \ (glTexParameteri, GL_TEXTURE_MIN_FILTER, GL_TEXTURE_MAG_FILTER, GL_LINEAR, GL_BGRA, GL_RGBA, GL_RGB, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_4_4_4_4_REV, - glGenTextures, glBindTexture, glTexImage2D, GL_TEXTURE_2D, GLuint) + glGenTextures, glBindTexture, glTexImage2D, GL_TEXTURE_2D, GLuint, + glDeleteTextures) from pytouhou.lib.sdl import load_png, create_rgb_surface from pytouhou.formats.thtx import Texture #TODO: perhaps define that elsewhere? @@ -24,85 +25,81 @@ from pytouhou.formats.thtx import Textur import os -cdef class TextureManager: - def __init__(self, loader=None): - self.loader = loader - self.textures = {} +class TextureId(int): + def __del__(self): + cdef GLuint texture = self + glDeleteTextures(1, &texture) - def __getitem__(self, key): - if not key in self.textures: - self.textures[key] = self.load_texture(key) - return self.textures[key] +class TextureManager(object): + def __init__(self, loader=None): + self.loader = loader - def preload(self, anm_wrapper): - for anm in anm_wrapper: - anm.texture = self.load_png_texture(anm.first_name, anm.secondary_name) + def load(self, anm_list): + for anm in anm_list: + if not hasattr(anm, 'texture'): + texture = decode_png(self.loader, anm.first_name, anm.secondary_name) + anm.texture = load_texture(texture) - def load_png_texture(self, first_name, secondary_name): - image_file = load_png(self.loader.get_file(os.path.basename(first_name))) - width, height = image_file.width, image_file.height +cdef decode_png(loader, first_name, secondary_name): + image_file = load_png(loader.get_file(os.path.basename(first_name))) + width, height = image_file.width, image_file.height - # Support only 32 bits RGBA. Paletted surfaces are awful to work with. - #TODO: verify it doesn’t blow up on big-endian systems. - new_image = create_rgb_surface(width, height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000) - new_image.blit(image_file) + # Support only 32 bits RGBA. Paletted surfaces are awful to work with. + #TODO: verify it doesn’t blow up on big-endian systems. + new_image = create_rgb_surface(width, height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000) + new_image.blit(image_file) - if secondary_name: - alpha_file = load_png(self.loader.get_file(os.path.basename(secondary_name))) - assert (width == alpha_file.width and - height == alpha_file.height) + if secondary_name: + alpha_file = load_png(loader.get_file(os.path.basename(secondary_name))) + assert (width == alpha_file.width and height == alpha_file.height) - new_alpha_file = create_rgb_surface(width, height, 24) - new_alpha_file.blit(alpha_file) + new_alpha_file = create_rgb_surface(width, height, 24) + new_alpha_file.blit(alpha_file) - new_image.set_alpha(new_alpha_file) + new_image.set_alpha(new_alpha_file) - return Texture(width, height, -4, new_image.pixels) + return Texture(width, height, -4, new_image.pixels) - def load_texture(self, key): - cdef GLuint id_ - - if not isinstance(key, Texture): - first_name, secondary_name = key - key = self.load_png_texture(first_name, secondary_name) +cdef load_texture(thtx): + cdef GLuint texture - if key.fmt == 1: - format_ = GL_BGRA - type_ = GL_UNSIGNED_BYTE - composants = GL_RGBA - elif key.fmt == 3: - format_ = GL_RGB - type_ = GL_UNSIGNED_SHORT_5_6_5 - composants = GL_RGB - elif key.fmt == 5: - format_ = GL_BGRA - type_ = GL_UNSIGNED_SHORT_4_4_4_4_REV - composants = GL_RGBA - elif key.fmt == 7: - format_ = GL_LUMINANCE - type_ = GL_UNSIGNED_BYTE - composants = GL_LUMINANCE - elif key.fmt == -4: #XXX: non-standard - format_ = GL_RGBA - type_ = GL_UNSIGNED_BYTE - composants = GL_RGBA - else: - raise Exception('Unknown texture type') + if thtx.fmt == 1: + format_ = GL_BGRA + type_ = GL_UNSIGNED_BYTE + composants = GL_RGBA + elif thtx.fmt == 3: + format_ = GL_RGB + type_ = GL_UNSIGNED_SHORT_5_6_5 + composants = GL_RGB + elif thtx.fmt == 5: + format_ = GL_BGRA + type_ = GL_UNSIGNED_SHORT_4_4_4_4_REV + composants = GL_RGBA + elif thtx.fmt == 7: + format_ = GL_LUMINANCE + type_ = GL_UNSIGNED_BYTE + composants = GL_LUMINANCE + elif thtx.fmt == -4: #XXX: non-standard + format_ = GL_RGBA + type_ = GL_UNSIGNED_BYTE + composants = GL_RGBA + else: + raise Exception('Unknown texture type') - glGenTextures(1, &id_) - glBindTexture(GL_TEXTURE_2D, id_) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) + glGenTextures(1, &texture) + glBindTexture(GL_TEXTURE_2D, texture) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) - glTexImage2D(GL_TEXTURE_2D, 0, - composants, - key.width, key.height, - 0, - format_, type_, - <char*>key.data) + glTexImage2D(GL_TEXTURE_2D, 0, + composants, + thtx.width, thtx.height, + 0, + format_, type_, + <char*>thtx.data) - return id_ + return TextureId(texture)