Mercurial > touhou
comparison pytouhou/ui/opengl/texture.pyx @ 513:5e3e0b09a531
Move the OpenGL backend to its own package.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Thu, 05 Dec 2013 02:16:31 +0100 |
parents | pytouhou/ui/texture.pyx@2e8ceaa85d5c |
children | b3193b43a86c |
comparison
equal
deleted
inserted
replaced
512:b39ad30c6620 | 513:5e3e0b09a531 |
---|---|
1 # -*- encoding: utf-8 -*- | |
2 ## | |
3 ## Copyright (C) 2011 Thibaut Girka <thib@sitedethib.com> | |
4 ## | |
5 ## This program is free software; you can redistribute it and/or modify | |
6 ## it under the terms of the GNU General Public License as published | |
7 ## by the Free Software Foundation; version 3 only. | |
8 ## | |
9 ## This program is distributed in the hope that it will be useful, | |
10 ## but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 ## GNU General Public License for more details. | |
13 ## | |
14 | |
15 from pytouhou.lib.opengl cimport \ | |
16 (glTexParameteri, GL_TEXTURE_MIN_FILTER, GL_TEXTURE_MAG_FILTER, | |
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, | |
19 glGenTextures, glBindTexture, glTexImage2D, GL_TEXTURE_2D, GLuint) | |
20 | |
21 from pytouhou.lib.sdl cimport load_png, create_rgb_surface | |
22 from pytouhou.formats.thtx import Texture #TODO: perhaps define that elsewhere? | |
23 from pytouhou.game.text cimport NativeText | |
24 | |
25 import os | |
26 | |
27 | |
28 cdef class TextureManager: | |
29 def __init__(self, loader=None, renderer=None, texture_class=None): | |
30 self.loader = loader | |
31 self.renderer = renderer | |
32 self.texture_class = texture_class | |
33 | |
34 | |
35 cdef void load(self, dict anms): | |
36 for anm in sorted(anms.values(), key=is_ascii): | |
37 for entry in anm: | |
38 if not hasattr(entry, 'texture'): | |
39 texture = decode_png(self.loader, entry.first_name, entry.secondary_name) | |
40 elif not isinstance(entry.texture, self.texture_class): | |
41 texture = entry.texture | |
42 entry.texture = self.texture_class(load_texture(texture), self.renderer) | |
43 anms.clear() | |
44 | |
45 | |
46 def is_ascii(anm): | |
47 return anm[0].first_name.endswith('ascii.png') | |
48 | |
49 | |
50 cdef class FontManager: | |
51 def __init__(self, fontname, fontsize=16, renderer=None, texture_class=None): | |
52 self.font = Font(fontname, fontsize) | |
53 self.renderer = renderer | |
54 self.texture_class = texture_class | |
55 | |
56 | |
57 cdef void load(self, list labels): | |
58 cdef NativeText label | |
59 | |
60 for label in labels: | |
61 if label.texture is None: | |
62 surface = self.font.render(label.text) | |
63 label.width, label.height = surface.surface.w, surface.surface.h | |
64 | |
65 if label.align == 'center': | |
66 label.x -= label.width // 2 | |
67 elif label.align == 'right': | |
68 label.x -= label.width | |
69 else: | |
70 assert label.align == 'left' | |
71 | |
72 texture = Texture(label.width, label.height, -4, surface.pixels) | |
73 label.texture = self.texture_class(load_texture(texture), self.renderer) | |
74 | |
75 | |
76 cdef decode_png(loader, first_name, secondary_name): | |
77 image_file = load_png(loader.get_file(os.path.basename(first_name))) | |
78 width, height = image_file.surface.w, image_file.surface.h | |
79 | |
80 # Support only 32 bits RGBA. Paletted surfaces are awful to work with. | |
81 #TODO: verify it doesn’t blow up on big-endian systems. | |
82 new_image = create_rgb_surface(width, height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000) | |
83 new_image.blit(image_file) | |
84 | |
85 if secondary_name: | |
86 alpha_file = load_png(loader.get_file(os.path.basename(secondary_name))) | |
87 assert (width == alpha_file.surface.w and height == alpha_file.surface.h) | |
88 | |
89 new_alpha_file = create_rgb_surface(width, height, 24) | |
90 new_alpha_file.blit(alpha_file) | |
91 | |
92 new_image.set_alpha(new_alpha_file) | |
93 | |
94 return Texture(width, height, -4, new_image.pixels) | |
95 | |
96 | |
97 cdef GLuint load_texture(thtx): | |
98 cdef GLuint texture | |
99 | |
100 if thtx.fmt == 1: | |
101 format_ = GL_BGRA | |
102 type_ = GL_UNSIGNED_BYTE | |
103 composants = GL_RGBA | |
104 elif thtx.fmt == 3: | |
105 format_ = GL_RGB | |
106 type_ = GL_UNSIGNED_SHORT_5_6_5 | |
107 composants = GL_RGB | |
108 elif thtx.fmt == 5: | |
109 format_ = GL_BGRA | |
110 type_ = GL_UNSIGNED_SHORT_4_4_4_4_REV | |
111 composants = GL_RGBA | |
112 elif thtx.fmt == 7: | |
113 format_ = GL_LUMINANCE | |
114 type_ = GL_UNSIGNED_BYTE | |
115 composants = GL_LUMINANCE | |
116 elif thtx.fmt == -4: #XXX: non-standard | |
117 format_ = GL_RGBA | |
118 type_ = GL_UNSIGNED_BYTE | |
119 composants = GL_RGBA | |
120 else: | |
121 raise Exception('Unknown texture type') | |
122 | |
123 glGenTextures(1, &texture) | |
124 glBindTexture(GL_TEXTURE_2D, texture) | |
125 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) | |
126 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) | |
127 | |
128 glTexImage2D(GL_TEXTURE_2D, 0, | |
129 composants, | |
130 thtx.width, thtx.height, | |
131 0, | |
132 format_, type_, | |
133 <char*>thtx.data) | |
134 | |
135 return texture |