# HG changeset patch # User Emmanuel Gil Peyrot # Date 1374001635 -7200 # Node ID 1104dc2553ee430fb832c5205e4fd4f11cfd13ab # Parent f4d76d3d6f2a50ecddebe3b8133907452ce2b2d3 Make the anmviewer use the new architecture. diff --git a/README b/README --- a/README +++ b/README @@ -14,7 +14,7 @@ Dependencies: Running: * Python2 (>= 2.6) * Cython - * Pyglet + * A working OpenGL driver * SDL2 * SDL2_image, SDL2_mixer diff --git a/anmviewer b/anmviewer --- a/anmviewer +++ b/anmviewer @@ -19,9 +19,8 @@ import os import pyximport pyximport.install() +from pytouhou.ui.window import Window from pytouhou.resource.loader import Loader -from pytouhou.game.sprite import Sprite -from pytouhou.vm.anmrunner import ANMRunner from pytouhou.ui.anmrenderer import ANMRenderer @@ -29,10 +28,13 @@ def main(path, data, name, script, sprit resource_loader = Loader() resource_loader.scan_archives(os.path.join(path, name) for name in data) + window = Window((384, 448), fixed_pipeline=fixed_pipeline, sound=False) + # Get out animation anm_wrapper = resource_loader.get_anm_wrapper(name.split(',')) - anm = ANMRenderer(resource_loader, anm_wrapper, script, sprites, fixed_pipeline) - anm.start() + anm = ANMRenderer(window, resource_loader, anm_wrapper, script, sprites) + window.set_runner(anm) + window.run() parser = argparse.ArgumentParser(description='Viewer of ANM files, archives containing animations used in Touhou games.') diff --git a/pytouhou/ui/anmrenderer.py b/pytouhou/ui/anmrenderer.pyx rename from pytouhou/ui/anmrenderer.py rename to pytouhou/ui/anmrenderer.pyx --- a/pytouhou/ui/anmrenderer.py +++ b/pytouhou/ui/anmrenderer.pyx @@ -12,44 +12,32 @@ ## GNU General Public License for more details. ## -import pyglet -import traceback - -from pyglet.gl import (glMatrixMode, glEnable, - glHint, glEnableClientState, glViewport, - glLoadMatrixf, GL_PROJECTION, GL_MODELVIEW, - GL_TEXTURE_2D, GL_BLEND, - GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST, - GL_COLOR_ARRAY, GL_VERTEX_ARRAY, GL_TEXTURE_COORD_ARRAY, - glClearColor, glClear, GL_COLOR_BUFFER_BIT, - glGenBuffers) +from pytouhou.lib.opengl cimport \ + (glClearColor, glClear, GL_COLOR_BUFFER_BIT) from pytouhou.game.sprite import Sprite from pytouhou.vm.anmrunner import ANMRunner from pytouhou.utils.helpers import get_logger -from pytouhou.utils.maths import perspective, setup_camera +from pytouhou.utils.maths cimport perspective, setup_camera from .renderer import Renderer from .shaders.eosd import GameShader -from ctypes import c_uint +from pytouhou.lib import sdl logger = get_logger(__name__) -class ANMRenderer(pyglet.window.Window, Renderer): - def __init__(self, resource_loader, anm_wrapper, index=0, sprites=False, - fixed_pipeline=False): - Renderer.__init__(self, resource_loader) - self.texture_manager.preload(resource_loader.instanced_anms.values()) +class ANMRenderer(Renderer): + def __init__(self, window, resource_loader, anm_wrapper, index=0, sprites=False): + self.use_fixed_pipeline = window.use_fixed_pipeline #XXX - width, height = 384, 448 - pyglet.window.Window.__init__(self, width=width, height=height, - caption='PyTouhou', resizable=False) + Renderer.__init__(self, resource_loader) - self.use_fixed_pipeline = fixed_pipeline + self.window = window + self.texture_manager.preload(resource_loader.instanced_anms.values()) self._anm_wrapper = anm_wrapper self.sprites = sprites @@ -59,94 +47,26 @@ class ANMRenderer(pyglet.window.Window, self.load(index) self.objects = [self] - self.x = width / 2 - self.y = height / 2 + self.width = 384 + self.height = 448 + + self.x = self.width / 2 + self.y = self.height / 2 def start(self, width=384, height=448): - if (width, height) != (self.width, self.height): - self.set_size(width, height) - - # Initialize OpenGL - glEnable(GL_BLEND) - if self.use_fixed_pipeline: - glEnable(GL_TEXTURE_2D) - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) - glEnableClientState(GL_COLOR_ARRAY) - glEnableClientState(GL_VERTEX_ARRAY) - glEnableClientState(GL_TEXTURE_COORD_ARRAY) + self.window.set_size(width, height) # Switch to game projection - proj = perspective(30, float(self.width) / float(self.height), + proj = perspective(30, float(width) / float(height), 101010101./2010101., 101010101./10101.) view = setup_camera(0, 0, 1) - if not self.use_fixed_pipeline: - shader = GameShader() - - vbo_array = (c_uint * 1)() - glGenBuffers(1, vbo_array) - self.vbo, = vbo_array - - mvp = view * proj - shader.bind() - shader.uniform_matrixf('mvp', mvp.get_c_data()) - else: - glMatrixMode(GL_PROJECTION) - glLoadMatrixf(proj.get_c_data()) - - glMatrixMode(GL_MODELVIEW) - glLoadMatrixf(view.get_c_data()) - - # Use our own loop to ensure 60 fps - pyglet.clock.set_fps_limit(60) - while not self.has_exit: - pyglet.clock.tick() - self.dispatch_events() - self.update() - self.flip() - - - def on_resize(self, width, height): - glViewport(0, 0, width, height) - + shader = GameShader() - def _event_text_symbol(self, ev): - # XXX: Ugly workaround to a pyglet bug on X11 - #TODO: fix that bug in pyglet - try: - return pyglet.window.Window._event_text_symbol(self, ev) - except Exception as exc: - logger.warn('Pyglet error: %s', traceback.format_exc(exc)) - return None, None - - - def on_key_press(self, symbol, modifiers): - if symbol == pyglet.window.key.ESCAPE: - self.has_exit = True - elif symbol == pyglet.window.key.W: - self.load() - elif symbol == pyglet.window.key.X: - self.x, self.y = {(192, 224): (0, 0), - (0, 0): (-224, 0), - (-224, 0): (192, 224)}[(self.x, self.y)] - elif symbol == pyglet.window.key.C: - self.force_allow_dest_offset = not self.force_allow_dest_offset - self.load() - elif symbol == pyglet.window.key.LEFT: - self.change(-1) - elif symbol == pyglet.window.key.RIGHT: - self.change(+1) - elif symbol == pyglet.window.key.TAB: - self.toggle_sprites() - elif symbol == pyglet.window.key.SPACE: - self.toggle_clear_color() - elif symbol >= pyglet.window.key.F1 and symbol <= pyglet.window.key.F12: - interrupt = symbol - pyglet.window.key.F1 + 1 - if modifiers & pyglet.window.key.MOD_SHIFT: - interrupt += 12 - if not self.sprites: - self.anmrunner.interrupt(interrupt) + mvp = view * proj + shader.bind() + shader.uniform_matrix('mvp', mvp) def load(self, index=None): @@ -192,14 +112,60 @@ class ANMRenderer(pyglet.window.Window, def update(self): + sdl.SCANCODE_C = 6 + sdl.SCANCODE_TAB = 43 + sdl.SCANCODE_SPACE = 44 + sdl.SCANCODE_F1 = 58 + sdl.SCANCODE_F12 = 69 + for event in sdl.poll_events(): + type_ = event[0] + if type_ == sdl.KEYDOWN: + scancode = event[1] + if scancode == sdl.SCANCODE_Z: + self.load() + elif scancode == sdl.SCANCODE_X: + self.x, self.y = {(192, 224): (0, 0), + (0, 0): (-224, 0), + (-224, 0): (192, 224)}[(self.x, self.y)] + elif scancode == sdl.SCANCODE_C: + self.force_allow_dest_offset = not self.force_allow_dest_offset + self.load() + elif scancode == sdl.SCANCODE_LEFT: + self.change(-1) + elif scancode == sdl.SCANCODE_RIGHT: + self.change(+1) + elif scancode == sdl.SCANCODE_TAB: + self.toggle_sprites() + elif scancode == sdl.SCANCODE_SPACE: + self.toggle_clear_color() + elif sdl.SCANCODE_F1 <= scancode <= sdl.SCANCODE_F12: + interrupt = scancode - sdl.SCANCODE_F1 + 1 + keys = sdl.get_keyboard_state() + if keys[sdl.SCANCODE_LSHIFT]: + interrupt += 12 + if not self.sprites: + self.anmrunner.interrupt(interrupt) + elif scancode == sdl.SCANCODE_ESCAPE: + return False + elif type_ == sdl.QUIT: + return False + elif type_ == sdl.WINDOWEVENT: + event_ = event[1] + if event_ == sdl.WINDOWEVENT_RESIZED: + self.window.set_size(event[2], event[3]) + if not self.sprites: - self.anmrunner.run_frame() + self.anmrunner.run_frame() if self.force_allow_dest_offset: self.sprite.allow_dest_offset = True - glClearColor(*self.clear_color) + glClearColor(self.clear_color[0], self.clear_color[1], self.clear_color[2], self.clear_color[3]) glClear(GL_COLOR_BUFFER_BIT) if not self.sprite.removed: self.render_elements([self]) + return True + + def finish(self): + pass diff --git a/pytouhou/ui/anmrenderer.pyxbld b/pytouhou/ui/anmrenderer.pyxbld new file mode 120000 --- /dev/null +++ b/pytouhou/ui/anmrenderer.pyxbld @@ -0,0 +1,1 @@ +../lib/opengl.pyxbld \ No newline at end of file