changeset 37:a10e3f44a883

Add alpha (anm0 instruction 3) support
author Thibaut Girka <thib@sitedethib.com>
date Sun, 14 Aug 2011 18:00:06 +0200
parents f46c18872796
children cb5b27011044
files eclviewer.py pytouhou/game/background.py pytouhou/game/enemymanager.py pytouhou/game/sprite.py stageviewer.py
diffstat 5 files changed, 42 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/eclviewer.py
+++ b/eclviewer.py
@@ -41,6 +41,7 @@ def main(path, stage_num):
     glHint(GL_FOG_HINT, GL_NICEST)
     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
+    glEnableClientState(GL_COLOR_ARRAY)
     glEnableClientState(GL_VERTEX_ARRAY)
     glEnableClientState(GL_TEXTURE_COORD_ARRAY)
 
@@ -87,7 +88,8 @@ def main(path, stage_num):
             background.update(frame)
 
             # Draw everything
-            glClear(GL_COLOR_BUFFER_BIT)
+#            glClearColor(0.0, 0.0, 1.0, 0)
+#            glClear(GL_COLOR_BUFFER_BIT)
 
             fog_b, fog_g, fog_r, _, fog_start, fog_end = background.fog_interpolator.values
             x, y, z = background.position_interpolator.values
@@ -111,10 +113,11 @@ def main(path, stage_num):
             #print(glGetFloat(GL_MODELVIEW_MATRIX))
             glTranslatef(-x, -y, -z)
 
-            for texture_key, (nb_vertices, vertices, uvs) in background.objects_by_texture.items():
+            for texture_key, (nb_vertices, vertices, uvs, colors) in background.objects_by_texture.items():
                 glBindTexture(GL_TEXTURE_2D, texture_manager[texture_key])
                 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)
 
             #TODO
@@ -129,10 +132,11 @@ def main(path, stage_num):
                       192., 224., 750 - 835.979370, 0., -1., 0.) #TODO: 750 might not be accurate
 
             glDisable(GL_FOG)
-            for texture_key, (nb_vertices, vertices, uvs) in enemy_manager.objects_by_texture.items():
+            for texture_key, (nb_vertices, vertices, uvs, colors) in enemy_manager.objects_by_texture.items():
                 glBindTexture(GL_TEXTURE_2D, texture_manager[texture_key])
                 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)
             glEnable(GL_FOG)
 
--- a/pytouhou/game/background.py
+++ b/pytouhou/game/background.py
@@ -29,10 +29,11 @@ class Background(object):
             obj_id = self.stage.objects.index(obj)
 
             obj_instance = []
-            for face_vertices, face_uvs in self.objects[obj_id]:
+            for face_vertices, face_uvs, face_colors in self.objects[obj_id]:
                 obj_instance.append((tuple((x + ox, y + oy, z + oz)
                                         for x, y, z in face_vertices),
-                                    face_uvs))
+                                    face_uvs,
+                                    face_colors))
             self.object_instances.append(obj_instance)
         # Z-sorting
         def keyfunc(obj):
@@ -40,12 +41,14 @@ class Background(object):
         self.object_instances.sort(key=keyfunc, reverse=True)
 
 
-    def object_instances_to_vertices_uvs(self):
+    def object_instances_to_vertices_uvs_colors(self):
         vertices = tuple(vertex for obj in self.object_instances
                             for face in obj for vertex in face[0])
         uvs = tuple(uv for obj in self.object_instances
                             for face in obj for uv in face[1])
-        return vertices, uvs
+        colors = tuple(color for obj in self.object_instances
+                            for face in obj for color in face[2])
+        return vertices, uvs, colors
 
 
     def build_objects(self):
@@ -56,23 +59,26 @@ class Background(object):
                 #TODO: per-texture rendering
                 anm, sprite = self.anm_wrapper.get_sprite(script_index)
                 if sprite.update():
-                    sprite.update_uvs_vertices(width_override, height_override)
+                    sprite.update_vertices_uvs_colors(width_override, height_override)
                 uvs, vertices = sprite._uvs, tuple((x + ox, y + oy, z + oz) for x, y, z in sprite._vertices)
-                faces.append((vertices, uvs))
+                colors = sprite._colors
+                faces.append((vertices, uvs, colors))
             self.objects.append(faces)
 
 
     def update(self, frame):
         if not self.objects_by_texture:
-            vertices, uvs = self.object_instances_to_vertices_uvs()
+            vertices, uvs, colors = self.object_instances_to_vertices_uvs_colors()
             nb_vertices = len(vertices)
             vertices_format = 'f' * (3 * nb_vertices)
             uvs_format = 'f' * (2 * nb_vertices)
+            colors_format = 'B' * (4 * nb_vertices)
             vertices = struct.pack(vertices_format, *chain(*vertices))
             uvs = struct.pack(uvs_format, *chain(*uvs))
+            colors = struct.pack(colors_format, *chain(*colors))
             assert len(self.anm_wrapper.anm_files) == 1 #TODO
             anm = self.anm_wrapper.anm_files[0]
-            self.objects_by_texture = {(anm.first_name, anm.secondary_name): (nb_vertices, vertices, uvs)}
+            self.objects_by_texture = {(anm.first_name, anm.secondary_name): (nb_vertices, vertices, uvs, colors)}
 
         for frame_num, message_type, args in self.stage.script:
             if frame_num == frame:
--- a/pytouhou/game/enemymanager.py
+++ b/pytouhou/game/enemymanager.py
@@ -123,10 +123,11 @@ class Enemy(object):
         objects_by_texture = {}
         key = self.anm.first_name, self.anm.secondary_name
         if not key in objects_by_texture:
-            objects_by_texture[key] = (0, [], [])
+            objects_by_texture[key] = (0, [], [], [])
         vertices = tuple((x + self.x, y + self.y, z) for x, y, z in self.sprite._vertices)
         objects_by_texture[key][1].extend(vertices)
         objects_by_texture[key][2].extend(self.sprite._uvs)
+        objects_by_texture[key][3].extend(self.sprite._colors)
         #TODO: effects/bullet launch
         return objects_by_texture
 
@@ -166,7 +167,7 @@ class Enemy(object):
             changed = self.sprite.update()
             visible = self.is_visible(384, 448)
             if changed and visible:
-                self.sprite.update_uvs_vertices()
+                self.sprite.update_vertices_uvs_colors()
             elif not self.sprite.playing:
                 visible = False
                 self.sprite = None
@@ -220,14 +221,16 @@ class EnemyManager(object):
         self.objects_by_texture = {}
         for enemy in visible_enemies:
             if enemy.is_visible(384, 448): #TODO
-                for key, (count, vertices, uvs) in enemy.get_objects_by_texture().items():
+                for key, (count, vertices, uvs, colors) in enemy.get_objects_by_texture().items():
                     if not key in self.objects_by_texture:
-                        self.objects_by_texture[key] = (0, [], [])
+                        self.objects_by_texture[key] = (0, [], [], [])
                     self.objects_by_texture[key][1].extend(vertices)
                     self.objects_by_texture[key][2].extend(uvs)
-        for key, (nb_vertices, vertices, uvs) in self.objects_by_texture.items():
+                    self.objects_by_texture[key][3].extend(colors)
+        for key, (nb_vertices, vertices, uvs, colors) in self.objects_by_texture.items():
             nb_vertices = len(vertices)
             vertices = pack('f' * (3 * nb_vertices), *chain(*vertices))
             uvs = pack('f' * (2 * nb_vertices), *chain(*uvs))
-            self.objects_by_texture[key] = (nb_vertices, vertices, uvs)
+            colors = pack('B' * (4 * nb_vertices), *chain(*colors))
+            self.objects_by_texture[key] = (nb_vertices, vertices, uvs, colors)
 
--- a/pytouhou/game/sprite.py
+++ b/pytouhou/game/sprite.py
@@ -28,11 +28,13 @@ class Sprite(object):
         self.keep_still = False
         self.playing = True
         self.frame = 0
+        self.alpha = 255
         self._uvs = []
         self._vertices = []
+        self._colors = []
 
 
-    def update_uvs_vertices(self, override_width=0, override_height=0):
+    def update_vertices_uvs_colors(self, override_width=0, override_height=0):
         vertmat = Matrix([[-.5,     .5,     .5,    -.5],
                           [-.5,    -.5,     .5,     .5],
                           [ .0,     .0,     .0,     .0],
@@ -66,6 +68,7 @@ class Sprite(object):
 
         d = vertmat.data
         assert (d[3][0], d[3][1], d[3][2], d[3][3]) == (1., 1., 1., 1.)
+        self._colors = [(255, 255, 255, self.alpha)] * 4
         self._uvs, self._vertices = uvs, zip(d[0], d[1], d[2])
 
 
@@ -83,10 +86,15 @@ class Sprite(object):
                     frame, instr_type, data = script[self.instruction_pointer]
                     if frame == self.frame:
                         changed = True
+                        if instr_type == 0:
+                            self.playing = False
+                            return False
                         if instr_type == 1:
                             self.texcoords = self.anm.sprites[unpack('<I', data)[0]]
                         elif instr_type == 2:
                             self.rescale = unpack('<ff', data)
+                        elif instr_type == 3:
+                            self.alpha = unpack('<I', data)[0] % 256 #TODO
                         elif instr_type == 5:
                             self.frame, = unpack('<I', data)
                             self.instruction_pointer = 0
--- a/stageviewer.py
+++ b/stageviewer.py
@@ -40,6 +40,7 @@ def main(path, stage_num):
     glHint(GL_FOG_HINT, GL_NICEST)
     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
+    glEnableClientState(GL_COLOR_ARRAY)
     glEnableClientState(GL_VERTEX_ARRAY)
     glEnableClientState(GL_TEXTURE_COORD_ARRAY)
 
@@ -95,10 +96,11 @@ def main(path, stage_num):
             #print(glGetFloat(GL_MODELVIEW_MATRIX))
             glTranslatef(-x, -y, -z)
 
-            for texture_key, (nb_vertices, vertices, uvs) in background.objects_by_texture.items():
+            for texture_key, (nb_vertices, vertices, uvs, colors) in background.objects_by_texture.items():
                 glBindTexture(GL_TEXTURE_2D, texture_manager[texture_key])
                 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)
 
             #TODO: show the game itself