changeset 119:fad7b44cebf2

Switch from pygame + PyOpenGL to pyglet
author Thibaut Girka <thib@sitedethib.com>
date Wed, 07 Sep 2011 18:12:24 +0200
parents c596a1a69402
children 4300a832f033
files README eclviewer.py pytouhou/opengl/gamerenderer.py pytouhou/opengl/texture.py
diffstat 4 files changed, 65 insertions(+), 79 deletions(-) [+]
line wrap: on
line diff
--- a/README
+++ b/README
@@ -12,8 +12,7 @@ Dependencies:
 -------------
 
     * Python2 (>= 2.6)
-    * Pygame
-    * PyOpenGL
+    * Pyglet
 
 
 
--- a/eclviewer.py
+++ b/eclviewer.py
@@ -16,8 +16,6 @@
 import sys
 import os
 
-import pygame
-
 from pytouhou.resource.loader import Loader
 from pytouhou.game.background import Background
 from pytouhou.opengl.gamerenderer import GameRenderer
@@ -37,36 +35,12 @@ def main(path, stage_num):
     background_anm_wrapper = resource_loader.get_anm_wrapper(('stg%dbg.anm' % stage_num,))
     background = Background(stage, background_anm_wrapper)
 
-    # Renderer
-    renderer = GameRenderer(resource_loader, game, background)
-    renderer.start()
-
     # Let's go!
     print(stage.name)
 
     # Main loop
-    clock = pygame.time.Clock()
-    while True:
-        # Check events
-        for event in pygame.event.get():
-            if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key in (pygame.K_ESCAPE, pygame.K_q)):
-                sys.exit(0)
-            elif event.type == pygame.KEYDOWN:
-                if event.key == pygame.K_RETURN and event.mod & pygame.KMOD_ALT:
-                    pygame.display.toggle_fullscreen()
-        keystate = 0 #TODO
-
-        # Update game
-        background.update(game.game_state.frame) #TODO
-        game.run_iter(keystate)
-
-        # Draw everything
-        renderer.render()
-
-        pygame.display.flip()
-
-        clock.tick(120)
-
+    renderer = GameRenderer(resource_loader, game, background)
+    renderer.start()
 
 
 try:
--- a/pytouhou/opengl/gamerenderer.py
+++ b/pytouhou/opengl/gamerenderer.py
@@ -15,34 +15,30 @@
 import struct
 from itertools import chain
 
-import pygame
-
-import OpenGL
-OpenGL.FORWARD_COMPATIBLE_ONLY = True
-from OpenGL.GL import *
-from OpenGL.GLU import *
-
+import pyglet
+from pyglet.gl import *
 
 from pytouhou.opengl.texture import TextureManager
 from pytouhou.opengl.sprite import get_sprite_rendering_data
 from pytouhou.opengl.background import get_background_rendering_data
 
 
-class GameRenderer(object):
+class GameRenderer(pyglet.window.Window):
     def __init__(self, resource_loader, game=None, background=None):
+        pyglet.window.Window.__init__(self, caption='PyTouhou', resizable=False)
+        self.keys = pyglet.window.key.KeyStateHandler()
+        self.push_handlers(self.keys)
+
         self.texture_manager = TextureManager(resource_loader)
 
+        self.fps_display =         pyglet.clock.ClockDisplay()
+
         self.game = game
         self.background = background
 
-        self.window = None
-
 
     def start(self, width=384, height=448):
-        # Initialize pygame
-        pygame.init()
-        self.window = pygame.display.set_mode((width, height),
-                                              pygame.OPENGL | pygame.DOUBLEBUF)
+        self.set_size(width, height)
 
         # Initialize OpenGL
         glMatrixMode(GL_PROJECTION)
@@ -59,6 +55,29 @@ class GameRenderer(object):
         glEnableClientState(GL_VERTEX_ARRAY)
         glEnableClientState(GL_TEXTURE_COORD_ARRAY)
 
+        pyglet.clock.schedule_interval(self.update, 1./120)
+        pyglet.app.run()
+
+
+    def on_resize(self, width, height):
+        glViewport(0, 0, width, height)
+
+
+
+    def update(self, dt):
+        if self.background:
+            self.background.update(self.game.game_state.frame)
+        if self.game:
+            self.game.run_iter(0) #TODO: self.keys...
+
+
+    def on_key_press(self, symbol, modifiers):
+        if symbol == pyglet.window.key.ESCAPE:
+            pyglet.app.exit()
+        # XXX: Fullscreen will be enabled the day pyglet stops sucking
+        elif symbol == pyglet.window.key.F11:
+            self.set_fullscreen(not self.fullscreen)
+
 
     def render_elements(self, elements):
         texture_manager = self.texture_manager
@@ -76,15 +95,18 @@ class GameRenderer(object):
 
         for (texture_key, blendfunc), (vertices, uvs, colors) in objects_by_texture.items():
             nb_vertices = len(vertices)
+            vertices = struct.pack(str(3 * nb_vertices) + 'f', *chain(*vertices))
+            uvs = struct.pack(str(2 * nb_vertices) + 'f', *chain(*uvs))
+            colors = struct.pack(str(4 * nb_vertices) + 'B', *chain(*colors))
             glBlendFunc(GL_SRC_ALPHA, (GL_ONE_MINUS_SRC_ALPHA, GL_ONE)[blendfunc])
-            glBindTexture(GL_TEXTURE_2D, texture_manager[texture_key])
-            glVertexPointer(3, GL_FLOAT, 0, struct.pack(str(3 * nb_vertices) + 'f', *chain(*vertices)))
-            glTexCoordPointer(2, GL_FLOAT, 0, struct.pack(str(2 * nb_vertices) + 'f', *chain(*uvs)))
-            glColorPointer(4, GL_UNSIGNED_BYTE, 0, struct.pack(str(4 * nb_vertices) + 'B', *chain(*colors)))
+            glBindTexture(GL_TEXTURE_2D, texture_manager[texture_key].id)
+            glVertexPointer(3, GL_FLOAT, 0, vertices)
+            glTexCoordPointer(2, GL_FLOAT, 0, uvs)
+            glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors)
             glDrawArrays(GL_QUADS, 0, nb_vertices)
 
 
-    def render(self):
+    def on_draw(self):
         glClear(GL_DEPTH_BUFFER_BIT)
 
         back = self.background
@@ -99,7 +121,7 @@ class GameRenderer(object):
             glFogi(GL_FOG_MODE, GL_LINEAR)
             glFogf(GL_FOG_START, fog_start)
             glFogf(GL_FOG_END,  fog_end)
-            glFogfv(GL_FOG_COLOR, (fog_r / 255., fog_g / 255., fog_b / 255., 1.))
+            glFogfv(GL_FOG_COLOR, (GLfloat * 4)(fog_r / 255., fog_g / 255., fog_b / 255., 1.))
 
             glMatrixMode(GL_MODELVIEW)
             glLoadIdentity()
@@ -115,7 +137,7 @@ class GameRenderer(object):
             glEnable(GL_DEPTH_TEST)
             for (texture_key, blendfunc), (nb_vertices, vertices, uvs, colors) in get_background_rendering_data(back):
                 glBlendFunc(GL_SRC_ALPHA, (GL_ONE_MINUS_SRC_ALPHA, GL_ONE)[blendfunc])
-                glBindTexture(GL_TEXTURE_2D, texture_manager[texture_key])
+                glBindTexture(GL_TEXTURE_2D, texture_manager[texture_key].id)
                 glVertexPointer(3, GL_FLOAT, 0, vertices)
                 glTexCoordPointer(2, GL_FLOAT, 0, uvs)
                 glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors)
@@ -124,7 +146,6 @@ class GameRenderer(object):
         else:
             glClear(GL_COLOR_BUFFER_BIT)
 
-
         if game is not None:
             glMatrixMode(GL_MODELVIEW)
             glLoadIdentity()
@@ -141,3 +162,10 @@ class GameRenderer(object):
             self.render_elements(game.game_state.bullets)
             glEnable(GL_FOG)
 
+        #TODO
+        glMatrixMode(GL_MODELVIEW)
+        glLoadIdentity()
+        gluLookAt(192., 224., 835.979370,
+                  192, 224., 0., 0., 1., 0.)
+        self.fps_display.draw()
+
--- a/pytouhou/opengl/texture.py
+++ b/pytouhou/opengl/texture.py
@@ -12,14 +12,9 @@
 ## GNU General Public License for more details.
 ##
 
-import pygame
+import pyglet
+from pyglet.gl import *
 import os
-from io import BytesIO
-
-import OpenGL
-OpenGL.FORWARD_COMPATIBLE_ONLY = True
-from OpenGL.GL import *
-from OpenGL.GLU import *
 
 
 class TextureManager(object):
@@ -47,32 +42,22 @@ class TextureManager(object):
     def load_texture(self, key):
         first_name, secondary_name = key
 
-        image_file = self.loader.get_file(os.path.basename(first_name))
-        textureSurface = pygame.image.load(image_file).convert_alpha()
+        image_file = pyglet.image.load(first_name, file=self.loader.get_file(os.path.basename(first_name)))
 
         if secondary_name:
-            alpha_image_file = self.loader.get_file(os.path.basename(secondary_name))
-            alphaSurface = pygame.image.load(alpha_image_file)
-            assert textureSurface.get_size() == alphaSurface.get_size()
-            for x in range(alphaSurface.get_width()):
-                for y in range(alphaSurface.get_height()):
-                    r, g, b, a = textureSurface.get_at((x, y))
-                    color2 = alphaSurface.get_at((x, y))
-                    textureSurface.set_at((x, y), (r, g, b, color2[0]))
+            alpha_file = pyglet.image.load(secondary_name, file=self.loader.get_file(os.path.basename(secondary_name)))
+            assert (image_file.width, image_file.height) == (alpha_file.width, image_file.height)
 
-        textureData = pygame.image.tostring(textureSurface, 'RGBA', 1)
+            data = image_file.get_data('RGB', image_file.width * 3)
+            alpha_data = alpha_file.get_data('RGB', image_file.width * 3)
+            image_file = pyglet.image.ImageData(image_file.width, image_file.height, 'RGBA', b''.join(data[i*3:i*3+3] + alpha_data[i*3] for i in range(image_file.width * image_file.height)))
 
-        width = textureSurface.get_width()
-        height = textureSurface.get_height()
-
-        texture = glGenTextures(1)
-        glBindTexture(GL_TEXTURE_2D, texture)
+            #TODO
 
-        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
-            GL_UNSIGNED_BYTE, textureData)
+        texture = image_file.get_texture()
 
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
+        glTexParameteri(texture.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
+        glTexParameteri(texture.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
 
         return texture