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()