Mercurial > touhou
comparison pytouhou/ui/opengl/renderer.pyx @ 558:94725968dabb
Use vertex array objects, to be compatible with OpenGL 3.1+ core profile.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Thu, 12 Dec 2013 13:47:17 +0100 |
parents | d6d9a711253d |
children | 1be60813f7cb |
comparison
equal
deleted
inserted
replaced
557:0f2af7552462 | 558:94725968dabb |
---|---|
30 glCheckFramebufferStatus, GL_FRAMEBUFFER, GL_TEXTURE_MIN_FILTER, | 30 glCheckFramebufferStatus, GL_FRAMEBUFFER, GL_TEXTURE_MIN_FILTER, |
31 GL_LINEAR, GL_TEXTURE_MAG_FILTER, GL_RGBA, GL_RENDERBUFFER, | 31 GL_LINEAR, GL_TEXTURE_MAG_FILTER, GL_RGBA, GL_RENDERBUFFER, |
32 GL_DEPTH_COMPONENT, GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, | 32 GL_DEPTH_COMPONENT, GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, |
33 GL_FRAMEBUFFER_COMPLETE, glClear, GL_COLOR_BUFFER_BIT, | 33 GL_FRAMEBUFFER_COMPLETE, glClear, GL_COLOR_BUFFER_BIT, |
34 GL_DEPTH_BUFFER_BIT, GLuint, glDeleteTextures, | 34 GL_DEPTH_BUFFER_BIT, GLuint, glDeleteTextures, |
35 GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW) | 35 GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, glGenVertexArrays, |
36 glDeleteVertexArrays, glBindVertexArray) | |
36 | 37 |
37 from pytouhou.lib.sdl import SDLError | 38 from pytouhou.lib.sdl import SDLError |
38 | 39 |
39 from pytouhou.game.element cimport Element | 40 from pytouhou.game.element cimport Element |
40 from .sprite cimport get_sprite_rendering_data | 41 from .sprite cimport get_sprite_rendering_data |
42 from .backend cimport use_vao | |
41 | 43 |
42 from pytouhou.utils.helpers import get_logger | 44 from pytouhou.utils.helpers import get_logger |
43 | 45 |
44 logger = get_logger(__name__) | 46 logger = get_logger(__name__) |
45 | 47 |
93 def __dealloc__(self): | 95 def __dealloc__(self): |
94 if not self.use_fixed_pipeline: | 96 if not self.use_fixed_pipeline: |
95 glDeleteBuffers(1, &self.framebuffer_vbo) | 97 glDeleteBuffers(1, &self.framebuffer_vbo) |
96 glDeleteBuffers(1, &self.vbo) | 98 glDeleteBuffers(1, &self.vbo) |
97 | 99 |
100 if use_vao: | |
101 glDeleteVertexArrays(1, &self.vao) | |
102 glDeleteVertexArrays(1, &self.framebuffer_vao) | |
103 | |
98 | 104 |
99 def __init__(self, resource_loader): | 105 def __init__(self, resource_loader): |
100 # Only used in modern GL. | 106 # Only used in modern GL. |
101 cdef unsigned short framebuffer_indices[6] | 107 cdef unsigned short framebuffer_indices[6] |
102 | 108 |
116 glGenBuffers(1, &self.framebuffer_ibo) | 122 glGenBuffers(1, &self.framebuffer_ibo) |
117 | 123 |
118 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.framebuffer_ibo) | 124 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.framebuffer_ibo) |
119 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(framebuffer_indices), framebuffer_indices, GL_STATIC_DRAW) | 125 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(framebuffer_indices), framebuffer_indices, GL_STATIC_DRAW) |
120 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) | 126 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) |
127 | |
128 if use_vao: | |
129 glGenVertexArrays(1, &self.vao) | |
130 glBindVertexArray(self.vao) | |
131 self.set_state() | |
132 | |
133 glGenVertexArrays(1, &self.framebuffer_vao) | |
134 glBindVertexArray(self.framebuffer_vao) | |
135 self.set_framebuffer_state() | |
136 glBindVertexArray(0) | |
137 | |
138 | |
139 cdef void set_state(self) nogil: | |
140 glBindBuffer(GL_ARRAY_BUFFER, self.vbo) | |
141 | |
142 #TODO: find a way to use offsetof() instead of those ugly substractions. | |
143 glVertexAttribPointer(0, 3, GL_SHORT, False, sizeof(Vertex), <void*>0) | |
144 glEnableVertexAttribArray(0) | |
145 glVertexAttribPointer(1, 2, GL_FLOAT, False, sizeof(Vertex), <void*>8) | |
146 glEnableVertexAttribArray(1) | |
147 glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, True, sizeof(Vertex), <void*>16) | |
148 glEnableVertexAttribArray(2) | |
149 | |
150 glBindBuffer(GL_ARRAY_BUFFER, 0) | |
151 | |
152 | |
153 cdef void set_framebuffer_state(self) nogil: | |
154 glBindBuffer(GL_ARRAY_BUFFER, self.framebuffer_vbo) | |
155 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.framebuffer_ibo) | |
156 | |
157 #TODO: find a way to use offsetof() instead of those ugly hardcoded values. | |
158 glVertexAttribPointer(0, 2, GL_SHORT, False, sizeof(PassthroughVertex), <void*>0) | |
159 glEnableVertexAttribArray(0) | |
160 glVertexAttribPointer(1, 2, GL_FLOAT, False, sizeof(PassthroughVertex), <void*>4) | |
161 glEnableVertexAttribArray(1) | |
162 | |
163 glBindBuffer(GL_ARRAY_BUFFER, 0) | |
121 | 164 |
122 | 165 |
123 cdef void render_elements(self, elements): | 166 cdef void render_elements(self, elements): |
124 cdef Element element | 167 cdef Element element |
125 | 168 |
166 glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &self.vertex_buffer[0].u) | 209 glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &self.vertex_buffer[0].u) |
167 glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), &self.vertex_buffer[0].r) | 210 glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), &self.vertex_buffer[0].r) |
168 else: | 211 else: |
169 glBindBuffer(GL_ARRAY_BUFFER, self.vbo) | 212 glBindBuffer(GL_ARRAY_BUFFER, self.vbo) |
170 glBufferData(GL_ARRAY_BUFFER, nb_vertices * sizeof(Vertex), &self.vertex_buffer[0], GL_DYNAMIC_DRAW) | 213 glBufferData(GL_ARRAY_BUFFER, nb_vertices * sizeof(Vertex), &self.vertex_buffer[0], GL_DYNAMIC_DRAW) |
171 | 214 glBindBuffer(GL_ARRAY_BUFFER, 0) |
172 #TODO: find a way to use offsetof() instead of those ugly hardcoded values. | 215 |
173 glVertexAttribPointer(0, 3, GL_SHORT, False, sizeof(Vertex), <void*>0) | 216 if use_vao: |
174 glEnableVertexAttribArray(0) | 217 glBindVertexArray(self.vao) |
175 glVertexAttribPointer(1, 2, GL_FLOAT, False, sizeof(Vertex), <void*>8) | 218 else: |
176 glEnableVertexAttribArray(1) | 219 self.set_state() |
177 glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, True, sizeof(Vertex), <void*>16) | |
178 glEnableVertexAttribArray(2) | |
179 | 220 |
180 # Don’t change the state when it’s not needed. | 221 # Don’t change the state when it’s not needed. |
181 previous_blendfunc = -1 | 222 previous_blendfunc = -1 |
182 previous_texture = -1 | 223 previous_texture = -1 |
183 | 224 |
198 previous_blendfunc = blendfunc | 239 previous_blendfunc = blendfunc |
199 previous_texture = texture | 240 previous_texture = texture |
200 | 241 |
201 glBindTexture(GL_TEXTURE_2D, 0) | 242 glBindTexture(GL_TEXTURE_2D, 0) |
202 | 243 |
203 if not self.use_fixed_pipeline: | 244 if not self.use_fixed_pipeline and use_vao: |
204 glBindBuffer(GL_ARRAY_BUFFER, 0) | 245 glBindVertexArray(0) |
205 | 246 |
206 | 247 |
207 cdef void render_quads(self, rects, colors, GLuint texture): | 248 cdef void render_quads(self, rects, colors, GLuint texture): |
208 # There is nothing that batch more than two quads on the same texture, currently. | 249 # There is nothing that batch more than two quads on the same texture, currently. |
209 cdef Vertex buf[8] | 250 cdef Vertex buf[8] |
226 glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &buf[0].u) | 267 glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &buf[0].u) |
227 glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), &buf[0].r) | 268 glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), &buf[0].r) |
228 else: | 269 else: |
229 glBindBuffer(GL_ARRAY_BUFFER, self.vbo) | 270 glBindBuffer(GL_ARRAY_BUFFER, self.vbo) |
230 glBufferData(GL_ARRAY_BUFFER, 4 * length * sizeof(Vertex), buf, GL_DYNAMIC_DRAW) | 271 glBufferData(GL_ARRAY_BUFFER, 4 * length * sizeof(Vertex), buf, GL_DYNAMIC_DRAW) |
231 | 272 glBindBuffer(GL_ARRAY_BUFFER, 0) |
232 #TODO: find a way to use offsetof() instead of those ugly hardcoded values. | 273 |
233 glVertexAttribPointer(0, 3, GL_SHORT, False, sizeof(Vertex), <void*>0) | 274 if use_vao: |
234 glEnableVertexAttribArray(0) | 275 glBindVertexArray(self.vao) |
235 glVertexAttribPointer(1, 2, GL_FLOAT, False, sizeof(Vertex), <void*>8) | 276 else: |
236 glEnableVertexAttribArray(1) | 277 self.set_state() |
237 glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, True, sizeof(Vertex), <void*>16) | |
238 glEnableVertexAttribArray(2) | |
239 | 278 |
240 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) | 279 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) |
241 glBindTexture(GL_TEXTURE_2D, texture) | 280 glBindTexture(GL_TEXTURE_2D, texture) |
242 glDrawElements(GL_TRIANGLES, 6 * length, GL_UNSIGNED_SHORT, indices) | 281 glDrawElements(GL_TRIANGLES, 6 * length, GL_UNSIGNED_SHORT, indices) |
243 | |
244 if not self.use_fixed_pipeline: | |
245 glBindBuffer(GL_ARRAY_BUFFER, 0) | |
246 | 282 |
247 | 283 |
248 cdef void render_framebuffer(self, Framebuffer fb): | 284 cdef void render_framebuffer(self, Framebuffer fb): |
249 cdef PassthroughVertex[4] buf | 285 cdef PassthroughVertex[4] buf |
250 | 286 |
253 glBindFramebuffer(GL_FRAMEBUFFER, 0) | 289 glBindFramebuffer(GL_FRAMEBUFFER, 0) |
254 glViewport(self.x, self.y, self.width, self.height) | 290 glViewport(self.x, self.y, self.width, self.height) |
255 glBlendFunc(GL_ONE, GL_ZERO) | 291 glBlendFunc(GL_ONE, GL_ZERO) |
256 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) | 292 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) |
257 | 293 |
258 glBindBuffer(GL_ARRAY_BUFFER, self.framebuffer_vbo) | 294 if use_vao: |
259 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.framebuffer_ibo) | 295 glBindVertexArray(self.framebuffer_vao) |
260 | 296 else: |
261 #TODO: find a way to use offsetof() instead of those ugly hardcoded values. | 297 self.set_framebuffer_state() |
262 glVertexAttribPointer(0, 2, GL_SHORT, False, sizeof(PassthroughVertex), <void*>0) | |
263 glEnableVertexAttribArray(0) | |
264 glVertexAttribPointer(1, 2, GL_FLOAT, False, sizeof(PassthroughVertex), <void*>4) | |
265 glEnableVertexAttribArray(1) | |
266 | 298 |
267 buf[0] = PassthroughVertex(fb.x, fb.y, 0, 1) | 299 buf[0] = PassthroughVertex(fb.x, fb.y, 0, 1) |
268 buf[1] = PassthroughVertex(fb.x + fb.width, fb.y, 1, 1) | 300 buf[1] = PassthroughVertex(fb.x + fb.width, fb.y, 1, 1) |
269 buf[2] = PassthroughVertex(fb.x + fb.width, fb.y + fb.height, 1, 0) | 301 buf[2] = PassthroughVertex(fb.x + fb.width, fb.y + fb.height, 1, 0) |
270 buf[3] = PassthroughVertex(fb.x, fb.y + fb.height, 0, 0) | 302 buf[3] = PassthroughVertex(fb.x, fb.y + fb.height, 0, 0) |
271 glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(PassthroughVertex), buf, GL_DYNAMIC_DRAW) | 303 |
304 glBindBuffer(GL_ARRAY_BUFFER, self.framebuffer_vbo) | |
305 glBufferData(GL_ARRAY_BUFFER, sizeof(buf), buf, GL_DYNAMIC_DRAW) | |
306 glBindBuffer(GL_ARRAY_BUFFER, 0) | |
272 | 307 |
273 glBindTexture(GL_TEXTURE_2D, fb.texture) | 308 glBindTexture(GL_TEXTURE_2D, fb.texture) |
274 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, NULL) | 309 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, NULL) |
275 glBindTexture(GL_TEXTURE_2D, 0) | 310 glBindTexture(GL_TEXTURE_2D, 0) |
276 | 311 |
277 glBindBuffer(GL_ARRAY_BUFFER, 0) | 312 if use_vao: |
278 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) | 313 glBindVertexArray(0) |
314 else: | |
315 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) | |
279 | 316 |
280 | 317 |
281 cdef class Framebuffer: | 318 cdef class Framebuffer: |
282 def __init__(self, int x, int y, int width, int height): | 319 def __init__(self, int x, int y, int width, int height): |
283 self.x = x | 320 self.x = x |