Mercurial > touhou
diff pytouhou/ui/gamerenderer.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 | a71b912b45b7 |
line wrap: on
line diff
--- a/pytouhou/ui/gamerenderer.pyx +++ b/pytouhou/ui/gamerenderer.pyx @@ -16,25 +16,64 @@ from itertools import chain from pytouhou.lib.opengl cimport \ (glClear, glMatrixMode, glLoadIdentity, glLoadMatrixf, glDisable, - glEnable, glFogi, glFogf, glFogfv, - GL_PROJECTION, GL_MODELVIEW, GL_FOG, GL_FOG_MODE, GL_LINEAR, - GL_FOG_START, GL_FOG_END, GL_FOG_COLOR, GL_COLOR_BUFFER_BIT, GLfloat) + glEnable, glFogi, glFogf, glFogfv, GL_PROJECTION, GL_MODELVIEW, + GL_FOG, GL_FOG_MODE, GL_LINEAR, GL_FOG_START, GL_FOG_END, + GL_FOG_COLOR, GL_COLOR_BUFFER_BIT, GLfloat, glViewport, glScissor, + GL_SCISSOR_TEST, GL_DEPTH_BUFFER_BIT) -from pytouhou.utils.maths cimport setup_camera +from pytouhou.utils.maths cimport perspective, setup_camera, ortho_2d +from .shaders.eosd import GameShader, BackgroundShader + +from collections import namedtuple +Rect = namedtuple('Rect', 'x y w h') +Color = namedtuple('Color', 'r g b a') cdef class GameRenderer(Renderer): - def __init__(self, resource_loader): + def __init__(self, resource_loader, use_fixed_pipeline): + self.use_fixed_pipeline = use_fixed_pipeline #XXX + Renderer.__init__(self, resource_loader) + if not self.use_fixed_pipeline: + self.game_shader = GameShader() + self.background_shader = BackgroundShader() + self.interface_shader = self.game_shader - def render(self): + + cdef void load_background(self, background): + if background is not None: + self.background_renderer = BackgroundRenderer(self.use_fixed_pipeline) + self.background_renderer.load(background) + else: + self.background_renderer = None + + + cdef void start(self, game): + self.proj = perspective(30, float(game.width) / float(game.height), + 101010101./2010101., 101010101./10101.) + game_view = setup_camera(0, 0, 1) + self.game_mvp = game_view * self.proj + self.interface_mvp = ortho_2d(0., float(game.interface.width), float(game.interface.height), 0.) + + + cdef void render(self, game): + self.render_game(game) + self.render_text(game.texts + game.native_texts) + self.render_interface(game.interface, game.boss) + + + cdef void render_game(self, game): + cdef long game_x, game_y cdef float x, y, z, dx, dy, dz, fog_data[4], fog_start, fog_end cdef unsigned char fog_r, fog_g, fog_b cdef Matrix mvp - back = self.background - game = self.game + game_x, game_y = game.interface.game_pos + glViewport(game_x, game_y, game.width, game.height) + glClear(GL_DEPTH_BUFFER_BIT) + glScissor(game_x, game_y, game.width, game.height) + glEnable(GL_SCISSOR_TEST) if self.use_fixed_pipeline: glMatrixMode(GL_PROJECTION) @@ -50,7 +89,8 @@ cdef class GameRenderer(Renderer): self.game_shader.uniform_matrix('mvp', self.game_mvp) self.render_elements([game.spellcard_effect]) - elif back is not None: + elif self.background_renderer is not None: + back = self.background_renderer.background x, y, z = back.position_interpolator.values dx, dy, dz = back.position2_interpolator.values fog_b, fog_g, fog_r, fog_start, fog_end = back.fog_interpolator.values @@ -106,7 +146,7 @@ cdef class GameRenderer(Renderer): self.game_shader.bind() self.game_shader.uniform_matrix('mvp', self.game_mvp) - self.render_elements(enemy for enemy in game.enemies if enemy.visible) + self.render_elements([enemy for enemy in game.enemies if enemy.visible]) self.render_elements(game.effects) self.render_elements(chain(game.players_bullets, game.lasers_sprites(), @@ -115,3 +155,68 @@ cdef class GameRenderer(Renderer): self.render_elements(chain(game.bullets, game.lasers, game.cancelled_bullets, game.items, game.labels)) + + if game.msg_runner: + rect = Rect(48, 368, 288, 48) + color1 = Color(0, 0, 0, 192) + color2 = Color(0, 0, 0, 128) + self.render_quads([rect], [(color1, color1, color2, color2)], 0) + + glDisable(GL_SCISSOR_TEST) + + + cdef void render_text(self, texts): + if self.font_manager is None: + return + + labels = [label for label in texts if label is not None] + self.font_manager.load(labels) + + black = Color(0, 0, 0, 255) + + for label in labels: + if label is None: + continue + + rect = Rect(label.x, label.y, label.width, label.height) + gradient = [Color(*color, a=label.alpha) for color in label.gradient] + + if label.shadow: + shadow_rect = Rect(label.x + 1, label.y + 1, label.width, label.height) + shadow = [black._replace(a=label.alpha)] * 4 + self.render_quads([shadow_rect, rect], [shadow, gradient], label.texture) + else: + self.render_quads([rect], [gradient], label.texture) + + + cdef void render_interface(self, interface, game_boss): + elements = [] + + if self.use_fixed_pipeline: + glMatrixMode(GL_MODELVIEW) + glLoadMatrixf(self.interface_mvp.data) + glDisable(GL_FOG) + else: + self.interface_shader.bind() + self.interface_shader.uniform_matrix('mvp', self.interface_mvp) + glViewport(0, 0, interface.width, interface.height) + + items = [item for item in interface.items if item.anmrunner and item.anmrunner.running] + labels = interface.labels.values() + + if items: + # Redraw all the interface + elements.extend(items) + else: + # Redraw only changed labels + labels = [label for label in labels if label.changed] + + elements.extend(interface.level_start) + + if game_boss is not None: + elements.extend(interface.boss_items) + + elements.extend(labels) + self.render_elements(elements) + for label in labels: + label.changed = False