Mercurial > touhou
comparison pytouhou/ui/texture.pyx @ 393:9e2cbb2c2c64
Implement THTX, uncompressed textures stored inside ANM files, and use it instead of pyglet’s own wrapper.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Wed, 06 Feb 2013 19:55:54 +0100 |
parents | 45e1a9a37e66 |
children | 3a7b36324611 |
comparison
equal
deleted
inserted
replaced
392:45e1a9a37e66 | 393:9e2cbb2c2c64 |
---|---|
13 ## | 13 ## |
14 | 14 |
15 from libc.stdlib cimport malloc, free | 15 from libc.stdlib cimport malloc, free |
16 | 16 |
17 import pyglet | 17 import pyglet |
18 from pyglet.gl import (glTexParameteri, | 18 from pyglet.gl import (glTexParameteri, GL_TEXTURE_MIN_FILTER, |
19 GL_TEXTURE_MIN_FILTER, GL_TEXTURE_MAG_FILTER, GL_LINEAR) | 19 GL_TEXTURE_MAG_FILTER, GL_LINEAR, GL_BGRA, GL_RGBA, |
20 GL_RGB, GL_LUMINANCE, GL_UNSIGNED_BYTE, | |
21 GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_4_4_4_4_REV, | |
22 glGenTextures, glBindTexture, glTexImage2D, | |
23 GL_TEXTURE_2D) | |
24 from ctypes import c_uint, byref | |
20 import os | 25 import os |
26 | |
27 from pytouhou.formats.thtx import Texture #TODO: perhaps define that elsewhere? | |
21 | 28 |
22 | 29 |
23 cdef class TextureManager: | 30 cdef class TextureManager: |
24 def __init__(self, loader=None): | 31 def __init__(self, loader=None): |
25 self.loader = loader | 32 self.loader = loader |
31 self.textures[key] = self.load_texture(key) | 38 self.textures[key] = self.load_texture(key) |
32 return self.textures[key] | 39 return self.textures[key] |
33 | 40 |
34 | 41 |
35 def preload(self, anm_wrapper): | 42 def preload(self, anm_wrapper): |
36 try: | 43 for anm in anm_wrapper: |
37 anms = anm_wrapper.anm_files | 44 anm.texture = self.load_png_texture(anm.first_name, anm.secondary_name) |
38 except AttributeError: | |
39 anms = anm_wrapper | |
40 | |
41 for anm in anms: | |
42 key = anm.first_name, anm.secondary_name | |
43 texture = self[key] | |
44 | 45 |
45 | 46 |
46 def load_texture(self, key): | 47 def load_png_texture(self, first_name, secondary_name): |
47 cdef char *image, *alpha, *new_data | 48 cdef char *image, *alpha, *new_data |
48 cdef unsigned int i, width, height, pixels | 49 cdef unsigned int i, width, height, pixels |
49 | 50 |
50 first_name, secondary_name = key | |
51 | |
52 image_file = pyglet.image.load(first_name, file=self.loader.get_file(os.path.basename(first_name))) | 51 image_file = pyglet.image.load(first_name, file=self.loader.get_file(os.path.basename(first_name))) |
52 width, height = image_file.width, image_file.height | |
53 image_data = image_file.get_data('RGB', width * 3) | |
53 | 54 |
54 if secondary_name: | 55 if secondary_name: |
55 alpha_file = pyglet.image.load(secondary_name, file=self.loader.get_file(os.path.basename(secondary_name))) | 56 alpha_file = pyglet.image.load(secondary_name, file=self.loader.get_file(os.path.basename(secondary_name))) |
56 assert (image_file.width, image_file.height) == (alpha_file.width, image_file.height) | 57 assert (image_file.width, image_file.height) == (alpha_file.width, image_file.height) |
57 | 58 |
58 width, height = image_file.width, image_file.height | |
59 pixels = width * height | 59 pixels = width * height |
60 | 60 |
61 image_data = image_file.get_data('RGB', width * 3) | |
62 alpha_data = alpha_file.get_data('RGB', width * 3) | 61 alpha_data = alpha_file.get_data('RGB', width * 3) |
63 image = <char *>image_data | 62 image = <char *>image_data |
64 alpha = <char *>alpha_data | 63 alpha = <char *>alpha_data |
65 | 64 |
66 # TODO: further optimizations | 65 # TODO: further optimizations |
68 for i in range(pixels): | 67 for i in range(pixels): |
69 new_data[i*4] = image[i*3] | 68 new_data[i*4] = image[i*3] |
70 new_data[i*4+1] = image[i*3+1] | 69 new_data[i*4+1] = image[i*3+1] |
71 new_data[i*4+2] = image[i*3+2] | 70 new_data[i*4+2] = image[i*3+2] |
72 new_data[i*4+3] = alpha[i*3] | 71 new_data[i*4+3] = alpha[i*3] |
73 image_file = pyglet.image.ImageData(width, height, 'RGBA', new_data[:(pixels * 4)]) | 72 data = new_data[:(pixels * 4)] |
74 free(new_data) | 73 free(new_data) |
74 return Texture(width, height, -4, data) | |
75 | 75 |
76 texture = image_file.get_texture() | 76 return Texture(width, height, -3, image_data) |
77 | 77 |
78 glTexParameteri(texture.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR) | |
79 glTexParameteri(texture.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR) | |
80 | 78 |
81 return texture | 79 def load_texture(self, key): |
80 if not isinstance(key, Texture): | |
81 first_name, secondary_name = key | |
82 key = self.load_png_texture(first_name, secondary_name) | |
82 | 83 |
84 if key.fmt == 1: | |
85 format_ = GL_BGRA | |
86 type_ = GL_UNSIGNED_BYTE | |
87 composants = GL_RGBA | |
88 elif key.fmt == 3: | |
89 format_ = GL_RGB | |
90 type_ = GL_UNSIGNED_SHORT_5_6_5 | |
91 composants = GL_RGB | |
92 elif key.fmt == 5: | |
93 format_ = GL_BGRA | |
94 type_ = GL_UNSIGNED_SHORT_4_4_4_4_REV | |
95 composants = GL_RGBA | |
96 elif key.fmt == 7: | |
97 format_ = GL_LUMINANCE | |
98 type_ = GL_UNSIGNED_BYTE | |
99 composants = GL_LUMINANCE | |
100 elif key.fmt == -3: #XXX: non-standard, remove it! | |
101 format_ = GL_RGB | |
102 type_ = GL_UNSIGNED_BYTE | |
103 composants = GL_RGB | |
104 elif key.fmt == -4: #XXX: non-standard | |
105 format_ = GL_RGBA | |
106 type_ = GL_UNSIGNED_BYTE | |
107 composants = GL_RGBA | |
108 else: | |
109 raise Exception('Unknown texture type') | |
110 | |
111 id_ = c_uint() | |
112 glGenTextures(1, byref(id_)) | |
113 glBindTexture(GL_TEXTURE_2D, id_.value) | |
114 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) | |
115 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) | |
116 | |
117 glTexImage2D(GL_TEXTURE_2D, 0, | |
118 composants, | |
119 key.width, key.height, | |
120 0, | |
121 format_, type_, | |
122 key.data) | |
123 | |
124 return id_.value |