Mercurial > touhou
comparison pytouhou/ui/window.pyx @ 423:d8630c086926
Replace Pyglet with our own Cython OpenGL wrapper.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Tue, 16 Jul 2013 21:07:15 +0200 |
parents | pytouhou/ui/window.py@52829ebe2561 |
children | 2a352118c55a |
comparison
equal
deleted
inserted
replaced
422:52829ebe2561 | 423:d8630c086926 |
---|---|
1 # -*- encoding: utf-8 -*- | |
2 ## | |
3 ## Copyright (C) 2013 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> | |
4 ## | |
5 ## This program is free software; you can redistribute it and/or modify | |
6 ## it under the terms of the GNU General Public License as published | |
7 ## by the Free Software Foundation; version 3 only. | |
8 ## | |
9 ## This program is distributed in the hope that it will be useful, | |
10 ## but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 ## GNU General Public License for more details. | |
13 ## | |
14 | |
15 | |
16 from pytouhou.lib import sdl | |
17 | |
18 from pytouhou.lib.opengl cimport \ | |
19 (glEnable, glHint, glEnableClientState, GL_TEXTURE_2D, GL_BLEND, | |
20 GL_PERSPECTIVE_CORRECTION_HINT, GL_FOG_HINT, GL_NICEST, | |
21 GL_COLOR_ARRAY, GL_VERTEX_ARRAY, GL_TEXTURE_COORD_ARRAY) | |
22 | |
23 | |
24 class Clock(object): | |
25 def __init__(self, fps=None): | |
26 self._target_fps = 0 | |
27 self._ref_tick = 0 | |
28 self._ref_frame = 0 | |
29 self._fps_tick = 0 | |
30 self._fps_frame = 0 | |
31 self._rate = 0 | |
32 self.set_target_fps(fps) | |
33 | |
34 | |
35 def set_target_fps(self, fps): | |
36 self._target_fps = fps | |
37 self._ref_tick = 0 | |
38 self._fps_tick = 0 | |
39 | |
40 | |
41 def get_fps(self): | |
42 return self._rate | |
43 | |
44 | |
45 def tick(self): | |
46 current = sdl.get_ticks() | |
47 | |
48 if not self._ref_tick: | |
49 self._ref_tick = current | |
50 self._ref_frame = 0 | |
51 | |
52 if self._fps_frame >= (self._target_fps or 60): | |
53 self._rate = self._fps_frame * 1000. / (current - self._fps_tick) | |
54 self._fps_tick = current | |
55 self._fps_frame = 0 | |
56 | |
57 self._ref_frame += 1 | |
58 self._fps_frame += 1 | |
59 | |
60 target_tick = self._ref_tick | |
61 if self._target_fps: | |
62 target_tick += int(self._ref_frame * 1000 / self._target_fps) | |
63 | |
64 if current <= target_tick: | |
65 sdl.delay(target_tick - current) | |
66 else: | |
67 self._ref_tick = current | |
68 self._ref_frame = 0 | |
69 | |
70 | |
71 | |
72 class Window(object): | |
73 def __init__(self, size=None, double_buffer=True, fps_limit=60, | |
74 fixed_pipeline=False, sound=True): | |
75 self.fps_limit = fps_limit | |
76 self.use_fixed_pipeline = fixed_pipeline | |
77 self.runner = None | |
78 | |
79 sdl.init(sdl.INIT_VIDEO) | |
80 sdl.img_init(sdl.INIT_PNG) | |
81 if sound: | |
82 sdl.mix_init(0) | |
83 | |
84 sdl.gl_set_attribute(sdl.GL_CONTEXT_MAJOR_VERSION, 2) | |
85 sdl.gl_set_attribute(sdl.GL_CONTEXT_MINOR_VERSION, 1) | |
86 sdl.gl_set_attribute(sdl.GL_DOUBLEBUFFER, int(double_buffer)) | |
87 sdl.gl_set_attribute(sdl.GL_DEPTH_SIZE, 24) | |
88 | |
89 self.width, self.height = size if size else (640, 480) | |
90 | |
91 self.win = sdl.Window('PyTouhou', | |
92 sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, | |
93 self.width, self.height, | |
94 sdl.WINDOW_OPENGL | sdl.WINDOW_SHOWN) | |
95 self.win.gl_create_context() | |
96 | |
97 # Initialize OpenGL | |
98 glEnable(GL_BLEND) | |
99 if self.use_fixed_pipeline: | |
100 glEnable(GL_TEXTURE_2D) | |
101 glHint(GL_FOG_HINT, GL_NICEST) | |
102 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) | |
103 glEnableClientState(GL_COLOR_ARRAY) | |
104 glEnableClientState(GL_VERTEX_ARRAY) | |
105 glEnableClientState(GL_TEXTURE_COORD_ARRAY) | |
106 | |
107 # Initialize sound | |
108 if sound: | |
109 sdl.mix_open_audio(44100, sdl.DEFAULT_FORMAT, 2, 4096) | |
110 sdl.mix_allocate_channels(26) #TODO: make it dependent on the SFX number. | |
111 | |
112 self.clock = Clock(self.fps_limit) | |
113 | |
114 | |
115 def set_size(self, width, height): | |
116 self.win.set_window_size(width, height) | |
117 | |
118 | |
119 def set_runner(self, runner): | |
120 self.runner = runner | |
121 runner.start() | |
122 | |
123 | |
124 def run(self): | |
125 try: | |
126 while self.run_frame(): | |
127 pass | |
128 finally: | |
129 self.runner.finish() | |
130 | |
131 | |
132 def run_frame(self): | |
133 if self.runner: | |
134 running = self.runner.update() | |
135 self.win.gl_swap_window() | |
136 self.clock.tick() | |
137 return running | |
138 | |
139 | |
140 def __dealloc__(self): | |
141 self.win.gl_delete_context() | |
142 self.win.destroy_window() | |
143 sdl.mix_close_audio() | |
144 sdl.mix_quit() | |
145 sdl.img_quit() | |
146 sdl.quit() |