Mercurial > touhou
comparison pytouhou/ui/gamerunner.pyx @ 459:6e733ed817bd
Move every rendering function from gamerunner to gamerenderer.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Fri, 06 Sep 2013 22:35:54 +0200 |
parents | 1b56d62250ab |
children | 11708a1d0a1a |
comparison
equal
deleted
inserted
replaced
458:1b56d62250ab | 459:6e733ed817bd |
---|---|
12 ## GNU General Public License for more details. | 12 ## GNU General Public License for more details. |
13 ## | 13 ## |
14 | 14 |
15 from pytouhou.lib cimport sdl | 15 from pytouhou.lib cimport sdl |
16 | 16 |
17 from pytouhou.lib.opengl cimport \ | |
18 (glMatrixMode, glEnable, glDisable, glViewport, glScissor, | |
19 glLoadMatrixf, glGenBuffers, glDeleteBuffers, GL_MODELVIEW, | |
20 GL_FOG, GL_SCISSOR_TEST, glClear, GL_DEPTH_BUFFER_BIT) | |
21 | |
22 from pytouhou.utils.helpers import get_logger | |
23 from pytouhou.utils.maths cimport perspective, setup_camera, ortho_2d | |
24 | |
25 from .window cimport Window | 17 from .window cimport Window |
26 from .gamerenderer cimport GameRenderer | 18 from .gamerenderer cimport GameRenderer |
27 from .background import BackgroundRenderer | |
28 from .music import MusicPlayer, SFXPlayer, NullPlayer | 19 from .music import MusicPlayer, SFXPlayer, NullPlayer |
29 from .shaders.eosd import GameShader, BackgroundShader | |
30 | |
31 from collections import namedtuple | |
32 Rect = namedtuple('Rect', 'x y w h') | |
33 Color = namedtuple('Color', 'r g b a') | |
34 | |
35 logger = get_logger(__name__) | |
36 | 20 |
37 | 21 |
38 cdef class GameRunner(GameRenderer): | 22 cdef class GameRunner: |
23 cdef object game, background | |
24 cdef GameRenderer renderer | |
39 cdef Window window | 25 cdef Window window |
40 cdef object replay_level, save_keystates | 26 cdef object replay_level, save_keystates |
41 cdef long width, height, keystate | 27 cdef long width, height, keystate |
42 cdef bint skip | 28 cdef bint skip, use_fixed_pipeline |
43 | 29 |
44 def __init__(self, window, resource_loader, bint skip=False): | 30 def __init__(self, window, resource_loader, bint skip=False): |
45 self.use_fixed_pipeline = window.use_fixed_pipeline #XXX | 31 self.use_fixed_pipeline = window.use_fixed_pipeline #XXX |
46 | 32 |
47 GameRenderer.__init__(self, resource_loader) | 33 self.renderer = GameRenderer(resource_loader, self.use_fixed_pipeline) |
48 | 34 |
49 self.window = window | 35 self.window = window |
50 self.replay_level = None | 36 self.replay_level = None |
51 self.skip = skip | 37 self.skip = skip |
52 self.keystate = 0 | 38 self.keystate = 0 |
53 | 39 |
54 self.width = window.width #XXX | 40 self.width = window.width #XXX |
55 self.height = window.height #XXX | 41 self.height = window.height #XXX |
56 | 42 |
57 if not self.use_fixed_pipeline: | |
58 self.game_shader = GameShader() | |
59 self.background_shader = BackgroundShader() | |
60 self.interface_shader = self.game_shader | |
61 | |
62 | 43 |
63 def load_game(self, game=None, background=None, bgms=None, replay=None, save_keystates=None): | 44 def load_game(self, game=None, background=None, bgms=None, replay=None, save_keystates=None): |
64 self.game = game | 45 self.game = game |
65 self.background = background | 46 self.background = background |
66 | 47 |
67 self.texture_manager.load(game.resource_loader.instanced_anms.values()) | 48 self.renderer.texture_manager.load(game.resource_loader.instanced_anms.values()) |
68 | 49 self.renderer.load_background(background) |
69 if background: | |
70 self.background_renderer = BackgroundRenderer(self.use_fixed_pipeline) | |
71 self.background_renderer.prerender(background) | |
72 | 50 |
73 self.set_input(replay) | 51 self.set_input(replay) |
74 if replay and replay.levels[game.stage - 1]: | 52 if replay and replay.levels[game.stage - 1]: |
75 game.players[0].state.lives = self.replay_level.lives | 53 game.players[0].state.lives = self.replay_level.lives |
76 game.players[0].state.power = self.replay_level.power | 54 game.players[0].state.power = self.replay_level.power |
96 self.replay_level = replay.levels[self.game.stage-1] | 74 self.replay_level = replay.levels[self.game.stage-1] |
97 self.keys = self.replay_level.iter_keystates() | 75 self.keys = self.replay_level.iter_keystates() |
98 | 76 |
99 | 77 |
100 def start(self): | 78 def start(self): |
101 width = self.game.interface.width if self.game else 640 | 79 cdef long width, height |
102 height = self.game.interface.height if self.game else 480 | 80 width = self.game.interface.width if self.game is not None else 640 |
103 if (width, height) != (self.width, self.height): | 81 height = self.game.interface.height if self.game is not None else 480 |
82 if width != self.width or height != self.height: | |
104 self.window.set_size(width, height) | 83 self.window.set_size(width, height) |
105 | 84 |
106 self.proj = perspective(30, float(self.game.width) / float(self.game.height), | 85 self.renderer.start(self.game) |
107 101010101./2010101., 101010101./10101.) | |
108 game_view = setup_camera(0, 0, 1) | |
109 self.game_mvp = game_view * self.proj | |
110 self.interface_mvp = ortho_2d(0., float(self.width), float(self.height), 0.) | |
111 | 86 |
112 | 87 |
113 def finish(self): | 88 def finish(self): |
114 #TODO: actually clean after buffers are not needed anymore. | 89 #TODO: actually clean after buffers are not needed anymore. |
115 #if not self.use_fixed_pipeline: | 90 #if not self.use_fixed_pipeline: |
164 | 139 |
165 if self.save_keystates is not None: | 140 if self.save_keystates is not None: |
166 self.save_keystates.append(keystate) | 141 self.save_keystates.append(keystate) |
167 | 142 |
168 self.game.run_iter(keystate) | 143 self.game.run_iter(keystate) |
144 self.game.interface.labels['framerate'].set_text('%.2ffps' % self.window.get_fps()) | |
169 if not self.skip: | 145 if not self.skip: |
170 self.render_game() | 146 self.renderer.render(self.game) |
171 self.render_text() | |
172 self.render_interface() | |
173 return True | 147 return True |
174 | |
175 | |
176 def render_game(self): | |
177 # Switch to game projection | |
178 #TODO: move that to GameRenderer? | |
179 x, y = self.game.interface.game_pos | |
180 glViewport(x, y, self.game.width, self.game.height) | |
181 glClear(GL_DEPTH_BUFFER_BIT) | |
182 glScissor(x, y, self.game.width, self.game.height) | |
183 glEnable(GL_SCISSOR_TEST) | |
184 | |
185 GameRenderer.render(self) | |
186 | |
187 glDisable(GL_SCISSOR_TEST) | |
188 | |
189 if self.game.msg_runner: | |
190 rect = Rect(48, 368, 288, 48) | |
191 color1 = Color(0, 0, 0, 192) | |
192 color2 = Color(0, 0, 0, 128) | |
193 self.render_quads([rect], [(color1, color1, color2, color2)], 0) | |
194 | |
195 | |
196 def render_text(self): | |
197 if self.font_manager is None: | |
198 return | |
199 | |
200 labels = [label for label in self.game.texts + self.game.native_texts if label is not None] | |
201 self.font_manager.load(labels) | |
202 | |
203 black = Color(0, 0, 0, 255) | |
204 | |
205 for label in labels: | |
206 if label is None: | |
207 continue | |
208 | |
209 rect = Rect(label.x, label.y, label.width, label.height) | |
210 gradient = [Color(*color, a=label.alpha) for color in label.gradient] | |
211 | |
212 if label.shadow: | |
213 shadow_rect = Rect(label.x + 1, label.y + 1, label.width, label.height) | |
214 shadow = [black._replace(a=label.alpha)] * 4 | |
215 self.render_quads([shadow_rect, rect], [shadow, gradient], label.texture) | |
216 else: | |
217 self.render_quads([rect], [gradient], label.texture) | |
218 | |
219 | |
220 def render_interface(self): | |
221 elements = [] | |
222 interface = self.game.interface | |
223 interface.labels['framerate'].set_text('%.2ffps' % self.window.get_fps()) | |
224 | |
225 if self.use_fixed_pipeline: | |
226 glMatrixMode(GL_MODELVIEW) | |
227 glLoadMatrixf(self.interface_mvp.data) | |
228 glDisable(GL_FOG) | |
229 else: | |
230 self.interface_shader.bind() | |
231 self.interface_shader.uniform_matrix('mvp', self.interface_mvp) | |
232 glViewport(0, 0, self.width, self.height) | |
233 | |
234 items = [item for item in interface.items if item.anmrunner and item.anmrunner.running] | |
235 labels = interface.labels.values() | |
236 | |
237 if items: | |
238 # Redraw all the interface | |
239 elements.extend(items) | |
240 else: | |
241 # Redraw only changed labels | |
242 labels = [label for label in labels if label.changed] | |
243 | |
244 elements.extend(interface.level_start) | |
245 | |
246 if self.game.boss: | |
247 elements.extend(interface.boss_items) | |
248 | |
249 elements.extend(labels) | |
250 self.render_elements(elements) | |
251 for label in labels: | |
252 label.changed = False | |
253 |