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