Mercurial > touhou
comparison 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 |
comparison
equal
deleted
inserted
replaced
425:1104dc2553ee | 426:5d7bb2fd74f7 |
---|---|
14 | 14 |
15 from pytouhou.lib.opengl cimport \ | 15 from pytouhou.lib.opengl cimport \ |
16 (glTexParameteri, GL_TEXTURE_MIN_FILTER, GL_TEXTURE_MAG_FILTER, | 16 (glTexParameteri, GL_TEXTURE_MIN_FILTER, GL_TEXTURE_MAG_FILTER, |
17 GL_LINEAR, GL_BGRA, GL_RGBA, GL_RGB, GL_LUMINANCE, GL_UNSIGNED_BYTE, | 17 GL_LINEAR, GL_BGRA, GL_RGBA, GL_RGB, GL_LUMINANCE, GL_UNSIGNED_BYTE, |
18 GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_4_4_4_4_REV, | 18 GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_4_4_4_4_REV, |
19 glGenTextures, glBindTexture, glTexImage2D, GL_TEXTURE_2D, GLuint) | 19 glGenTextures, glBindTexture, glTexImage2D, GL_TEXTURE_2D, GLuint, |
20 glDeleteTextures) | |
20 | 21 |
21 from pytouhou.lib.sdl import load_png, create_rgb_surface | 22 from pytouhou.lib.sdl import load_png, create_rgb_surface |
22 from pytouhou.formats.thtx import Texture #TODO: perhaps define that elsewhere? | 23 from pytouhou.formats.thtx import Texture #TODO: perhaps define that elsewhere? |
23 | 24 |
24 import os | 25 import os |
25 | 26 |
26 | 27 |
27 cdef class TextureManager: | 28 class TextureId(int): |
29 def __del__(self): | |
30 cdef GLuint texture = self | |
31 glDeleteTextures(1, &texture) | |
32 | |
33 | |
34 class TextureManager(object): | |
28 def __init__(self, loader=None): | 35 def __init__(self, loader=None): |
29 self.loader = loader | 36 self.loader = loader |
30 self.textures = {} | |
31 | 37 |
32 | 38 |
33 def __getitem__(self, key): | 39 def load(self, anm_list): |
34 if not key in self.textures: | 40 for anm in anm_list: |
35 self.textures[key] = self.load_texture(key) | 41 if not hasattr(anm, 'texture'): |
36 return self.textures[key] | 42 texture = decode_png(self.loader, anm.first_name, anm.secondary_name) |
43 anm.texture = load_texture(texture) | |
37 | 44 |
38 | 45 |
39 def preload(self, anm_wrapper): | 46 cdef decode_png(loader, first_name, secondary_name): |
40 for anm in anm_wrapper: | 47 image_file = load_png(loader.get_file(os.path.basename(first_name))) |
41 anm.texture = self.load_png_texture(anm.first_name, anm.secondary_name) | 48 width, height = image_file.width, image_file.height |
49 | |
50 # Support only 32 bits RGBA. Paletted surfaces are awful to work with. | |
51 #TODO: verify it doesn’t blow up on big-endian systems. | |
52 new_image = create_rgb_surface(width, height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000) | |
53 new_image.blit(image_file) | |
54 | |
55 if secondary_name: | |
56 alpha_file = load_png(loader.get_file(os.path.basename(secondary_name))) | |
57 assert (width == alpha_file.width and height == alpha_file.height) | |
58 | |
59 new_alpha_file = create_rgb_surface(width, height, 24) | |
60 new_alpha_file.blit(alpha_file) | |
61 | |
62 new_image.set_alpha(new_alpha_file) | |
63 | |
64 return Texture(width, height, -4, new_image.pixels) | |
42 | 65 |
43 | 66 |
44 def load_png_texture(self, first_name, secondary_name): | 67 cdef load_texture(thtx): |
45 image_file = load_png(self.loader.get_file(os.path.basename(first_name))) | 68 cdef GLuint texture |
46 width, height = image_file.width, image_file.height | |
47 | 69 |
48 # Support only 32 bits RGBA. Paletted surfaces are awful to work with. | 70 if thtx.fmt == 1: |
49 #TODO: verify it doesn’t blow up on big-endian systems. | 71 format_ = GL_BGRA |
50 new_image = create_rgb_surface(width, height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000) | 72 type_ = GL_UNSIGNED_BYTE |
51 new_image.blit(image_file) | 73 composants = GL_RGBA |
74 elif thtx.fmt == 3: | |
75 format_ = GL_RGB | |
76 type_ = GL_UNSIGNED_SHORT_5_6_5 | |
77 composants = GL_RGB | |
78 elif thtx.fmt == 5: | |
79 format_ = GL_BGRA | |
80 type_ = GL_UNSIGNED_SHORT_4_4_4_4_REV | |
81 composants = GL_RGBA | |
82 elif thtx.fmt == 7: | |
83 format_ = GL_LUMINANCE | |
84 type_ = GL_UNSIGNED_BYTE | |
85 composants = GL_LUMINANCE | |
86 elif thtx.fmt == -4: #XXX: non-standard | |
87 format_ = GL_RGBA | |
88 type_ = GL_UNSIGNED_BYTE | |
89 composants = GL_RGBA | |
90 else: | |
91 raise Exception('Unknown texture type') | |
52 | 92 |
53 if secondary_name: | 93 glGenTextures(1, &texture) |
54 alpha_file = load_png(self.loader.get_file(os.path.basename(secondary_name))) | 94 glBindTexture(GL_TEXTURE_2D, texture) |
55 assert (width == alpha_file.width and | 95 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) |
56 height == alpha_file.height) | 96 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) |
57 | 97 |
58 new_alpha_file = create_rgb_surface(width, height, 24) | 98 glTexImage2D(GL_TEXTURE_2D, 0, |
59 new_alpha_file.blit(alpha_file) | 99 composants, |
100 thtx.width, thtx.height, | |
101 0, | |
102 format_, type_, | |
103 <char*>thtx.data) | |
60 | 104 |
61 new_image.set_alpha(new_alpha_file) | 105 return TextureId(texture) |
62 | |
63 return Texture(width, height, -4, new_image.pixels) | |
64 | |
65 | |
66 def load_texture(self, key): | |
67 cdef GLuint id_ | |
68 | |
69 if not isinstance(key, Texture): | |
70 first_name, secondary_name = key | |
71 key = self.load_png_texture(first_name, secondary_name) | |
72 | |
73 if key.fmt == 1: | |
74 format_ = GL_BGRA | |
75 type_ = GL_UNSIGNED_BYTE | |
76 composants = GL_RGBA | |
77 elif key.fmt == 3: | |
78 format_ = GL_RGB | |
79 type_ = GL_UNSIGNED_SHORT_5_6_5 | |
80 composants = GL_RGB | |
81 elif key.fmt == 5: | |
82 format_ = GL_BGRA | |
83 type_ = GL_UNSIGNED_SHORT_4_4_4_4_REV | |
84 composants = GL_RGBA | |
85 elif key.fmt == 7: | |
86 format_ = GL_LUMINANCE | |
87 type_ = GL_UNSIGNED_BYTE | |
88 composants = GL_LUMINANCE | |
89 elif key.fmt == -4: #XXX: non-standard | |
90 format_ = GL_RGBA | |
91 type_ = GL_UNSIGNED_BYTE | |
92 composants = GL_RGBA | |
93 else: | |
94 raise Exception('Unknown texture type') | |
95 | |
96 glGenTextures(1, &id_) | |
97 glBindTexture(GL_TEXTURE_2D, id_) | |
98 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) | |
99 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) | |
100 | |
101 glTexImage2D(GL_TEXTURE_2D, 0, | |
102 composants, | |
103 key.width, key.height, | |
104 0, | |
105 format_, type_, | |
106 <char*>key.data) | |
107 | |
108 return id_ |