Mercurial > touhou
comparison pytouhou/opengl/gamerenderer.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 | |
children | 340fcda8e64a |
comparison
equal
deleted
inserted
replaced
107:5d9052b9a4e8 | 108:2a03940deea3 |
---|---|
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 import struct | |
16 from itertools import chain | |
17 | |
18 import pygame | |
19 | |
20 import OpenGL | |
21 OpenGL.FORWARD_COMPATIBLE_ONLY = True | |
22 from OpenGL.GL import * | |
23 from OpenGL.GLU import * | |
24 | |
25 | |
26 from pytouhou.opengl.texture import TextureManager | |
27 from pytouhou.opengl.sprite import get_sprite_rendering_data | |
28 from pytouhou.opengl.background import get_background_rendering_data | |
29 | |
30 | |
31 class GameRenderer(object): | |
32 def __init__(self, resource_loader, game=None, background=None): | |
33 self.texture_manager = TextureManager(resource_loader) | |
34 | |
35 self.game = game | |
36 self.background = background | |
37 | |
38 self.window = None | |
39 | |
40 | |
41 def start(self, width=384, height=448): | |
42 # Initialize pygame | |
43 pygame.init() | |
44 self.window = pygame.display.set_mode((width, height), | |
45 pygame.OPENGL | pygame.DOUBLEBUF) | |
46 | |
47 # Initialize OpenGL | |
48 glMatrixMode(GL_PROJECTION) | |
49 glLoadIdentity() | |
50 gluPerspective(30, float(width)/float(height), | |
51 101010101./2010101., 101010101./10101.) | |
52 | |
53 glEnable(GL_BLEND) | |
54 glEnable(GL_TEXTURE_2D) | |
55 glEnable(GL_FOG) | |
56 glHint(GL_FOG_HINT, GL_NICEST) | |
57 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) | |
58 glEnableClientState(GL_COLOR_ARRAY) | |
59 glEnableClientState(GL_VERTEX_ARRAY) | |
60 glEnableClientState(GL_TEXTURE_COORD_ARRAY) | |
61 | |
62 | |
63 def render_elements(self, elements): | |
64 texture_manager = self.texture_manager | |
65 objects_by_texture = {} | |
66 for element in elements: | |
67 sprite = element._sprite | |
68 if sprite: | |
69 ox, oy = element.x, element.y | |
70 key, (vertices, uvs, colors) = get_sprite_rendering_data(sprite) | |
71 rec = objects_by_texture.setdefault(key, ([], [], [])) | |
72 vertices = ((x + ox, y + oy, z) for x, y, z in vertices) | |
73 rec[0].extend(vertices) | |
74 rec[1].extend(uvs) | |
75 rec[2].extend(colors) | |
76 | |
77 for (texture_key, blendfunc), (vertices, uvs, colors) in objects_by_texture.items(): | |
78 nb_vertices = len(vertices) | |
79 glBlendFunc(GL_SRC_ALPHA, (GL_ONE_MINUS_SRC_ALPHA, GL_ONE)[blendfunc]) | |
80 glBindTexture(GL_TEXTURE_2D, texture_manager[texture_key]) | |
81 glVertexPointer(3, GL_FLOAT, 0, struct.pack(str(3 * nb_vertices) + 'f', *chain(*vertices))) | |
82 glTexCoordPointer(2, GL_FLOAT, 0, struct.pack(str(2 * nb_vertices) + 'f', *chain(*uvs))) | |
83 glColorPointer(4, GL_UNSIGNED_BYTE, 0, struct.pack(str(4 * nb_vertices) + 'B', *chain(*colors))) | |
84 glDrawArrays(GL_QUADS, 0, nb_vertices) | |
85 | |
86 | |
87 def render(self): | |
88 glClear(GL_DEPTH_BUFFER_BIT) | |
89 | |
90 back = self.background | |
91 game = self.game | |
92 texture_manager = self.texture_manager | |
93 | |
94 if back is not None: | |
95 fog_b, fog_g, fog_r, _, fog_start, fog_end = back.fog_interpolator.values | |
96 x, y, z = back.position_interpolator.values | |
97 dx, dy, dz = back.position2_interpolator.values | |
98 | |
99 glFogi(GL_FOG_MODE, GL_LINEAR) | |
100 glFogf(GL_FOG_START, fog_start) | |
101 glFogf(GL_FOG_END, fog_end) | |
102 glFogfv(GL_FOG_COLOR, (fog_r / 255., fog_g / 255., fog_b / 255., 1.)) | |
103 | |
104 glMatrixMode(GL_MODELVIEW) | |
105 glLoadIdentity() | |
106 # Some explanations on the magic constants: | |
107 # 192. = 384. / 2. = width / 2. | |
108 # 224. = 448. / 2. = height / 2. | |
109 # 835.979370 = 224./math.tan(math.radians(15)) = (height/2.)/math.tan(math.radians(fov/2)) | |
110 # This is so that objects on the (O, x, y) plane use pixel coordinates | |
111 gluLookAt(192., 224., - 835.979370 * dz, | |
112 192. + dx, 224. - dy, 0., 0., -1., 0.) | |
113 glTranslatef(-x, -y, -z) | |
114 | |
115 glEnable(GL_DEPTH_TEST) | |
116 for (texture_key, blendfunc), (nb_vertices, vertices, uvs, colors) in get_background_rendering_data(back): | |
117 glBlendFunc(GL_SRC_ALPHA, (GL_ONE_MINUS_SRC_ALPHA, GL_ONE)[blendfunc]) | |
118 glBindTexture(GL_TEXTURE_2D, texture_manager[texture_key]) | |
119 glVertexPointer(3, GL_FLOAT, 0, vertices) | |
120 glTexCoordPointer(2, GL_FLOAT, 0, uvs) | |
121 glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors) | |
122 glDrawArrays(GL_QUADS, 0, nb_vertices) | |
123 glDisable(GL_DEPTH_TEST) | |
124 else: | |
125 glClear(GL_COLOR_BUFFER_BIT) | |
126 | |
127 | |
128 if game is not None: | |
129 glMatrixMode(GL_MODELVIEW) | |
130 glLoadIdentity() | |
131 # Some explanations on the magic constants: | |
132 # 192. = 384. / 2. = width / 2. | |
133 # 224. = 448. / 2. = height / 2. | |
134 # 835.979370 = 224./math.tan(math.radians(15)) = (height/2.)/math.tan(math.radians(fov/2)) | |
135 # This is so that objects on the (O, x, y) plane use pixel coordinates | |
136 gluLookAt(192., 224., - 835.979370, | |
137 192., 224., 0., 0., -1., 0.) | |
138 | |
139 glDisable(GL_FOG) | |
140 self.render_elements(game.enemies) | |
141 self.render_elements(game.game_state.bullets) | |
142 glEnable(GL_FOG) | |
143 |