comparison pytouhou/game/background.py @ 108:2a03940deea3

Move everything graphical to pytouhou.opengl!
author Thibaut Girka <thib@sitedethib.com>
date Tue, 06 Sep 2011 00:26:13 +0200
parents ca571697ec83
children 340fcda8e64a
comparison
equal deleted inserted replaced
107:5d9052b9a4e8 108:2a03940deea3
11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ## GNU General Public License for more details. 12 ## GNU General Public License for more details.
13 ## 13 ##
14 14
15 15
16 from io import BytesIO
17 import os
18 import struct
19 from itertools import chain
20
21 from pytouhou.utils.interpolator import Interpolator 16 from pytouhou.utils.interpolator import Interpolator
22 from pytouhou.vm.anmrunner import ANMRunner 17 from pytouhou.vm.anmrunner import ANMRunner
23 from pytouhou.game.sprite import Sprite 18 from pytouhou.game.sprite import Sprite
24 19
25 20
26 class Background(object): 21 class Background(object):
27 def __init__(self, stage, anm_wrapper): 22 def __init__(self, stage, anm_wrapper):
28 self.stage = stage 23 self.stage = stage
29 self.anm_wrapper = anm_wrapper 24 self.anm_wrapper = anm_wrapper
25
30 self.models = [] 26 self.models = []
31 self.object_instances = [] 27 self.object_instances = []
32 self.objects_by_texture = {} 28 self.anm_runners = []
33 29
34 self.position_interpolator = Interpolator((0, 0, 0)) 30 self.position_interpolator = Interpolator((0, 0, 0))
35 self.fog_interpolator = Interpolator((0, 0, 0, 0, 0)) 31 self.fog_interpolator = Interpolator((0, 0, 0, 0, 0))
36 self.position2_interpolator = Interpolator((0, 0, 0)) 32 self.position2_interpolator = Interpolator((0, 0, 0))
37 33
39 self.build_object_instances() 35 self.build_object_instances()
40 36
41 37
42 def build_object_instances(self): 38 def build_object_instances(self):
43 self.object_instances = [] 39 self.object_instances = []
44 for obj, ox, oy, oz in self.stage.object_instances: 40 for model_id, ox, oy, oz in self.stage.object_instances:
45 41 self.object_instances.append((ox, oy, oz, model_id, self.models[model_id]))
46 obj_instance = []
47 for face_vertices, face_uvs, face_colors in self.models[obj]:
48 obj_instance.append((tuple((x + ox, y + oy, z + oz)
49 for x, y, z in face_vertices),
50 face_uvs,
51 face_colors))
52 self.object_instances.append(obj_instance)
53 # Z-sorting 42 # Z-sorting
54 def keyfunc(obj): 43 def keyfunc(obj):
55 return min(z for face in obj for x, y, z in face[0]) 44 bounding_box = self.stage.models[obj[3]].bounding_box
45 return obj[2] + min(bounding_box[2], bounding_box[5])
56 self.object_instances.sort(key=keyfunc, reverse=True) 46 self.object_instances.sort(key=keyfunc, reverse=True)
57
58
59 def object_instances_to_vertices_uvs_colors(self):
60 vertices = tuple(vertex for obj in self.object_instances
61 for face in obj for vertex in face[0])
62 uvs = tuple(uv for obj in self.object_instances
63 for face in obj for uv in face[1])
64 colors = tuple(color for obj in self.object_instances
65 for face in obj for color in face[2])
66 return vertices, uvs, colors
67 47
68 48
69 def build_models(self): 49 def build_models(self):
70 self.models = [] 50 self.models = []
71 for i, obj in enumerate(self.stage.models): 51 for obj in self.stage.models:
72 faces = [] 52 quads = []
73 for script_index, ox, oy, oz, width_override, height_override in obj.quads: 53 for script_index, ox, oy, oz, width_override, height_override in obj.quads:
74 #TODO: per-texture rendering 54 #TODO: per-texture rendering
75 sprite = Sprite() 55 sprite = Sprite()
76 anm_runner = ANMRunner(self.anm_wrapper, script_index, sprite) 56 anm_runner = ANMRunner(self.anm_wrapper, script_index, sprite)
77 anm_runner.run_frame() 57 anm_runner.run_frame()
78 sprite.update(width_override, height_override) 58 sprite.update(width_override, height_override)
79 if sprite._changed: 59 quads.append((ox, oy, oz, width_override, height_override, sprite))
80 sprite.update_vertices_uvs_colors() 60 self.anm_runners.append(anm_runner)
81 uvs, vertices = sprite._uvs, tuple((x + ox, y + oy, z + oz) for x, y, z in sprite._vertices) 61 self.models.append(quads)
82 colors = sprite._colors
83 faces.append((vertices, uvs, colors))
84 self.models.append(faces)
85 62
86 63
87 def update(self, frame): 64 def update(self, frame):
88 if not self.objects_by_texture:
89 vertices, uvs, colors = self.object_instances_to_vertices_uvs_colors()
90 nb_vertices = len(vertices)
91 vertices_format = 'f' * (3 * nb_vertices)
92 uvs_format = 'f' * (2 * nb_vertices)
93 colors_format = 'B' * (4 * nb_vertices)
94 vertices = struct.pack(vertices_format, *chain(*vertices))
95 uvs = struct.pack(uvs_format, *chain(*uvs))
96 colors = struct.pack(colors_format, *chain(*colors))
97 assert len(self.anm_wrapper.anm_files) == 1 #TODO
98 anm = self.anm_wrapper.anm_files[0]
99 self.objects_by_texture = {((anm.first_name, anm.secondary_name), 0): (nb_vertices, vertices, uvs, colors)} #TODO: blendfunc
100
101 for frame_num, message_type, args in self.stage.script: 65 for frame_num, message_type, args in self.stage.script:
102 if frame_num == frame: 66 if frame_num == frame:
103 if message_type == 0: 67 if message_type == 0:
104 self.position_interpolator.set_interpolation_start(frame_num, args) 68 self.position_interpolator.set_interpolation_start(frame_num, args)
105 elif message_type == 1: 69 elif message_type == 1:
114 self.fog_interpolator.set_interpolation_end_frame(frame_num + duration) 78 self.fog_interpolator.set_interpolation_end_frame(frame_num + duration)
115 if frame_num > frame and message_type == 0: 79 if frame_num > frame and message_type == 0:
116 self.position_interpolator.set_interpolation_end(frame_num, args) 80 self.position_interpolator.set_interpolation_end(frame_num, args)
117 break 81 break
118 82
83 for anm_runner in tuple(self.anm_runners):
84 if not anm_runner.run_frame():
85 self.anm_runners.remove(anm_runner)
86
87 for model in self.models:
88 for ox, oy, oz, width_override, height_override, sprite in model:
89 sprite.update(width_override, height_override)
90
119 self.position2_interpolator.update(frame) 91 self.position2_interpolator.update(frame)
120 self.fog_interpolator.update(frame) 92 self.fog_interpolator.update(frame)
121 self.position_interpolator.update(frame) 93 self.position_interpolator.update(frame)
122 94