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