Mercurial > touhou
comparison pytouhou/ui/gamerenderer.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/gamerenderer.py@52829ebe2561 |
children | f4d76d3d6f2a |
comparison
equal
deleted
inserted
replaced
422:52829ebe2561 | 423:d8630c086926 |
---|---|
1 # -*- encoding: utf-8 -*- | |
2 ## | |
3 ## Copyright (C) 2011 Thibaut Girka <thib@sitedethib.com> | |
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 libc.stdlib cimport malloc, free | |
17 | |
18 from itertools import chain | |
19 | |
20 from pytouhou.lib.opengl cimport \ | |
21 (glClear, glMatrixMode, glLoadIdentity, glLoadMatrixf, glDisable, | |
22 glEnable, glFogi, glFogf, glFogfv, GL_DEPTH_BUFFER_BIT, | |
23 GL_PROJECTION, GL_MODELVIEW, GL_FOG, GL_FOG_MODE, GL_LINEAR, | |
24 GL_FOG_START, GL_FOG_END, GL_FOG_COLOR, GL_COLOR_BUFFER_BIT, GLfloat) | |
25 | |
26 from pytouhou.utils.matrix cimport Matrix, matrix_to_floats | |
27 from pytouhou.utils.maths cimport setup_camera | |
28 | |
29 from .renderer import Renderer | |
30 | |
31 | |
32 | |
33 class GameRenderer(Renderer): | |
34 def __init__(self, resource_loader): | |
35 Renderer.__init__(self, resource_loader) | |
36 | |
37 | |
38 def render(self): | |
39 cdef float* fog_data | |
40 | |
41 glClear(GL_DEPTH_BUFFER_BIT) | |
42 | |
43 back = self.background | |
44 game = self.game | |
45 | |
46 if self.use_fixed_pipeline: | |
47 glMatrixMode(GL_PROJECTION) | |
48 glLoadIdentity() | |
49 | |
50 if game is not None and game.spellcard_effect is not None: | |
51 if self.use_fixed_pipeline: | |
52 glMatrixMode(GL_MODELVIEW) | |
53 glLoadMatrixf(matrix_to_floats(self.game_mvp)) | |
54 glDisable(GL_FOG) | |
55 else: | |
56 self.game_shader.bind() | |
57 self.game_shader.uniform_matrixf('mvp', self.game_mvp.get_c_data()) | |
58 | |
59 self.render_elements([game.spellcard_effect]) | |
60 elif back is not None: | |
61 x, y, z = back.position_interpolator.values | |
62 dx, dy, dz = back.position2_interpolator.values | |
63 fog_b, fog_g, fog_r, fog_start, fog_end = back.fog_interpolator.values | |
64 | |
65 # Those two lines may come from the difference between Direct3D and | |
66 # OpenGL’s distance handling. The first one seem to calculate fog | |
67 # from the eye, while the second does that starting from the near | |
68 # plane. | |
69 #TODO: investigate, and use a variable to keep the near plane | |
70 # distance at a single place. | |
71 fog_start -= 101010101./2010101. | |
72 fog_end -= 101010101./2010101. | |
73 | |
74 model = Matrix() | |
75 model.data[3] = [-x, -y, -z, 1] | |
76 view = setup_camera(dx, dy, dz) | |
77 model_view_projection = model * view * self.proj | |
78 mvp = model_view_projection.get_c_data() | |
79 mvp_cython = matrix_to_floats(model_view_projection) | |
80 | |
81 if self.use_fixed_pipeline: | |
82 glMatrixMode(GL_MODELVIEW) | |
83 glLoadMatrixf(mvp_cython) | |
84 | |
85 glEnable(GL_FOG) | |
86 glFogi(GL_FOG_MODE, GL_LINEAR) | |
87 glFogf(GL_FOG_START, fog_start) | |
88 glFogf(GL_FOG_END, fog_end) | |
89 fog_data = <float*>malloc(4 * sizeof(float)) | |
90 fog_data[0] = fog_r / 255. | |
91 fog_data[1] = fog_g / 255. | |
92 fog_data[2] = fog_b / 255. | |
93 fog_data[3] = 1. | |
94 glFogfv(GL_FOG_COLOR, fog_data) | |
95 free(fog_data) | |
96 else: | |
97 self.background_shader.bind() | |
98 self.background_shader.uniform_matrixf('mvp', mvp) | |
99 | |
100 self.background_shader.uniformf('fog_scale', 1. / (fog_end - fog_start)) | |
101 self.background_shader.uniformf('fog_end', fog_end) | |
102 self.background_shader.uniformf('fog_color', fog_r / 255., fog_g / 255., fog_b / 255., 1.) | |
103 | |
104 self.background_renderer.render_background() | |
105 else: | |
106 glClear(GL_COLOR_BUFFER_BIT) | |
107 | |
108 if game is not None: | |
109 if self.use_fixed_pipeline: | |
110 glMatrixMode(GL_MODELVIEW) | |
111 glLoadMatrixf(matrix_to_floats(self.game_mvp)) | |
112 glDisable(GL_FOG) | |
113 else: | |
114 self.game_shader.bind() | |
115 self.game_shader.uniform_matrixf('mvp', self.game_mvp.get_c_data()) | |
116 | |
117 self.render_elements(enemy for enemy in game.enemies if enemy.visible) | |
118 self.render_elements(game.effects) | |
119 self.render_elements(chain(game.players_bullets, | |
120 game.lasers_sprites(), | |
121 game.players, | |
122 game.msg_sprites())) | |
123 self.render_elements(chain(game.bullets, game.lasers, | |
124 game.cancelled_bullets, game.items, | |
125 game.labels)) |