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