comparison pytouhou/ui/renderer.pyx @ 399:1c773544eaeb

Make the background use a single vbo and offsets, just like the 2D code.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Tue, 12 Feb 2013 19:19:31 +0100
parents 8d252cdb495f
children 9d790ca73c13
comparison
equal deleted inserted replaced
398:8d252cdb495f 399:1c773544eaeb
10 ## but WITHOUT ANY WARRANTY; without even the implied warranty of 10 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ## GNU General Public License for more details. 12 ## GNU General Public License for more details.
13 ## 13 ##
14 14
15 from libc.stdlib cimport malloc, free 15 from libc.stdlib cimport malloc, free, realloc
16 from libc.math cimport tan 16 from libc.math cimport tan
17 from math import radians 17 from math import radians
18 from itertools import chain 18 from itertools import chain
19 19
20 import ctypes 20 import ctypes
23 23
24 from pyglet.gl import (glVertexPointer, glTexCoordPointer, glColorPointer, 24 from pyglet.gl import (glVertexPointer, glTexCoordPointer, glColorPointer,
25 glVertexAttribPointer, glEnableVertexAttribArray, 25 glVertexAttribPointer, glEnableVertexAttribArray,
26 glBlendFunc, glBindTexture, glDrawElements, 26 glBlendFunc, glBindTexture, glDrawElements,
27 glBindBuffer, glBufferData, GL_ARRAY_BUFFER, 27 glBindBuffer, glBufferData, GL_ARRAY_BUFFER,
28 GL_DYNAMIC_DRAW, GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, 28 GL_DYNAMIC_DRAW, GL_STATIC_DRAW, GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT,
29 GL_INT, GL_FLOAT, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 29 GL_INT, GL_FLOAT, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
30 GL_ONE, GL_TEXTURE_2D, GL_TRIANGLES, 30 GL_ONE, GL_TEXTURE_2D, GL_TRIANGLES,
31 glEnable, glDisable, GL_DEPTH_TEST, glDrawArrays, GL_QUADS) 31 glEnable, glDisable, GL_DEPTH_TEST, glDrawArrays, GL_QUADS)
32 32
33 from .sprite cimport get_sprite_rendering_data 33 from .sprite cimport get_sprite_rendering_data
34 from .background import get_background_rendering_data
35 from .texture cimport TextureManager 34 from .texture cimport TextureManager
36 from pytouhou.utils.matrix cimport Matrix 35 from pytouhou.utils.matrix cimport Matrix
37 from pytouhou.utils.vector import Vector, normalize, cross, dot 36 from pytouhou.utils.vector import Vector, normalize, cross, dot
38 37
39 38
42 41
43 cdef class Renderer: 42 cdef class Renderer:
44 def __cinit__(self): 43 def __cinit__(self):
45 # Allocate buffers 44 # Allocate buffers
46 self.vertex_buffer = <Vertex*> malloc(MAX_ELEMENTS * sizeof(Vertex)) 45 self.vertex_buffer = <Vertex*> malloc(MAX_ELEMENTS * sizeof(Vertex))
46 self.background_vertex_buffer = <VertexFloat*> malloc(65536 * sizeof(Vertex))
47 47
48 48
49 def __dealloc__(self): 49 def __dealloc__(self):
50 free(self.vertex_buffer) 50 free(self.vertex_buffer)
51 free(self.background_vertex_buffer)
51 52
52 53
53 def __init__(self, resource_loader): 54 def __init__(self, resource_loader):
54 self.texture_manager = TextureManager(resource_loader) 55 self.texture_manager = TextureManager(resource_loader)
55 56
110 111
111 if not self.use_fixed_pipeline: 112 if not self.use_fixed_pipeline:
112 glBindBuffer(GL_ARRAY_BUFFER, 0) 113 glBindBuffer(GL_ARRAY_BUFFER, 0)
113 114
114 115
115 cpdef render_background(self, back): 116 cpdef render_background(self):
117 if self.use_fixed_pipeline:
118 glVertexPointer(3, GL_FLOAT, sizeof(VertexFloat), <long> &self.background_vertex_buffer[0].x)
119 glTexCoordPointer(2, GL_FLOAT, sizeof(VertexFloat), <long> &self.background_vertex_buffer[0].u)
120 glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexFloat), <long> &self.background_vertex_buffer[0].r)
121 else:
122 glBindBuffer(GL_ARRAY_BUFFER, self.back_vbo)
123
124 #TODO: find a way to use offsetof() instead of those ugly hardcoded values.
125 glVertexAttribPointer(0, 3, GL_FLOAT, False, sizeof(VertexFloat), 0)
126 glEnableVertexAttribArray(0)
127 glVertexAttribPointer(1, 2, GL_FLOAT, False, sizeof(VertexFloat), 12)
128 glEnableVertexAttribArray(1)
129 glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, True, sizeof(VertexFloat), 20)
130 glEnableVertexAttribArray(2)
131
116 glEnable(GL_DEPTH_TEST) 132 glEnable(GL_DEPTH_TEST)
117 for (texture_key, blendfunc), (nb_vertices, vertices, uvs, colors) in get_background_rendering_data(back): 133 glBlendFunc(GL_SRC_ALPHA, (GL_ONE_MINUS_SRC_ALPHA, GL_ONE)[self.blendfunc])
118 if self.use_fixed_pipeline: 134 glBindTexture(GL_TEXTURE_2D, self.texture_manager[self.texture_key])
119 glVertexPointer(3, GL_FLOAT, 0, vertices) 135 glDrawArrays(GL_QUADS, 0, self.nb_vertices)
120 glTexCoordPointer(2, GL_FLOAT, 0, uvs)
121 glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors)
122 else:
123 glVertexAttribPointer(0, 3, GL_FLOAT, False, 0, vertices)
124 glEnableVertexAttribArray(0)
125 glVertexAttribPointer(1, 2, GL_FLOAT, False, 0, uvs)
126 glEnableVertexAttribArray(1)
127 glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, True, 0, colors)
128 glEnableVertexAttribArray(2)
129 glBlendFunc(GL_SRC_ALPHA, (GL_ONE_MINUS_SRC_ALPHA, GL_ONE)[blendfunc])
130 glBindTexture(GL_TEXTURE_2D, self.texture_manager[texture_key])
131 glDrawArrays(GL_QUADS, 0, nb_vertices)
132 glDisable(GL_DEPTH_TEST) 136 glDisable(GL_DEPTH_TEST)
137
138 if not self.use_fixed_pipeline:
139 glBindBuffer(GL_ARRAY_BUFFER, 0)
140
141
142 cpdef prerender_background(self, background):
143 cdef float ox, oy, oz, ox2, oy2, oz2
144 cdef unsigned short nb_vertices = 0
145 cdef VertexFloat* vertex_buffer
146
147 vertex_buffer = self.background_vertex_buffer
148
149 for ox, oy, oz, model_id, model in background.object_instances:
150 for ox2, oy2, oz2, width_override, height_override, sprite in model:
151 #TODO: view frustum culling
152 key, (vertices, uvs, colors) = get_sprite_rendering_data(sprite)
153 (x1, y1, z1), (x2, y2, z2), (x3, y3, z3), (x4, y4, z4) = vertices
154 left, right, bottom, top = uvs
155 r, g, b, a = colors
156
157 vertex_buffer[nb_vertices] = VertexFloat(x1 + ox + ox2, y1 + oy + oy2, z1 + oz + oz2, left, bottom, r, g, b, a)
158 vertex_buffer[nb_vertices+1] = VertexFloat(x2 + ox + ox2, y2 + oy + oy2, z2 + oz + oz2, right, bottom, r, g, b, a)
159 vertex_buffer[nb_vertices+2] = VertexFloat(x3 + ox + ox2, y3 + oy + oy2, z3 + oz + oz2, right, top, r, g, b, a)
160 vertex_buffer[nb_vertices+3] = VertexFloat(x4 + ox + ox2, y4 + oy + oy2, z4 + oz + oz2, left, top, r, g, b, a)
161
162 nb_vertices += 4
163
164 self.texture_key, self.blendfunc = key
165 self.nb_vertices = nb_vertices
166 self.background_vertex_buffer = <VertexFloat*> realloc(vertex_buffer, nb_vertices * sizeof(VertexFloat))
167
168 if not self.use_fixed_pipeline:
169 glBindBuffer(GL_ARRAY_BUFFER, self.back_vbo)
170 glBufferData(GL_ARRAY_BUFFER, nb_vertices * sizeof(VertexFloat), <long> &self.background_vertex_buffer[0], GL_STATIC_DRAW)
171 glBindBuffer(GL_ARRAY_BUFFER, 0)
133 172
134 173
135 cpdef ortho_2d(self, left, right, bottom, top): 174 cpdef ortho_2d(self, left, right, bottom, top):
136 mat = Matrix() 175 mat = Matrix()
137 mat[0][0] = 2 / (right - left) 176 mat[0][0] = 2 / (right - left)