Mercurial > touhou
diff pytouhou/ui/renderer.pyx @ 505:bfea9e9a6845
Manage the texture-specific indices in the Texture, and some more renderer optimisations.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Fri, 01 Nov 2013 14:45:53 +0100 |
parents | c622eaf64428 |
children |
line wrap: on
line diff
--- a/pytouhou/ui/renderer.pyx +++ b/pytouhou/ui/renderer.pyx @@ -31,20 +31,26 @@ from pytouhou.lib.opengl cimport \ GL_LINEAR, GL_TEXTURE_MAG_FILTER, GL_RGBA, GL_RENDERBUFFER, GL_DEPTH_COMPONENT, GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_COMPLETE, glClear, GL_COLOR_BUFFER_BIT, - GL_DEPTH_BUFFER_BIT) + GL_DEPTH_BUFFER_BIT, GLuint, glDeleteTextures) from pytouhou.lib.sdl import SDLError from pytouhou.game.element cimport Element from .sprite cimport get_sprite_rendering_data -from .texture import TextureManager, FontManager from pytouhou.utils.helpers import get_logger logger = get_logger(__name__) -DEF MAX_ELEMENTS = 640*4*3 +cdef class Texture: + def __cinit__(self, GLuint texture, Renderer renderer): + self.texture = texture + for i in xrange(2): + renderer.indices[texture][i] = self.indices[i] + + def __dealloc__(self): + glDeleteTextures(1, &self.texture) cdef long find_objects(Renderer self, object elements) except -1: @@ -64,23 +70,17 @@ cdef long find_objects(Renderer self, ob cdef class Renderer: - def __cinit__(self): - self.vertex_buffer = <Vertex*> malloc(MAX_ELEMENTS * sizeof(Vertex)) - - def __dealloc__(self): - free(self.vertex_buffer) - if not self.use_fixed_pipeline: glDeleteBuffers(1, &self.framebuffer_vbo) glDeleteBuffers(1, &self.vbo) def __init__(self, resource_loader): - self.texture_manager = TextureManager(resource_loader, self) + self.texture_manager = TextureManager(resource_loader, self, Texture) font_name = join(resource_loader.game_dir, 'font.ttf') try: - self.font_manager = FontManager(font_name, 16, self) + self.font_manager = FontManager(font_name, 16, self, Texture) except SDLError: self.font_manager = None logger.error('Font file “%s” not found, disabling text rendering altogether.', font_name) @@ -90,36 +90,29 @@ cdef class Renderer: glGenBuffers(1, &self.framebuffer_vbo) - def add_texture(self, int texture): - for i in xrange(2): - self.indices[i][texture] = <unsigned short*> malloc(65536 * sizeof(unsigned short)) - - - def remove_texture(self, int texture): - for i in xrange(2): - free(self.indices[i][texture]) - - cdef void render_elements(self, elements): cdef int key cdef int x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4, ox, oy cdef float left, right, bottom, top cdef unsigned char r, g, b, a + nb_elements = find_objects(self, elements) + if not nb_elements: + return + nb_vertices = 0 memset(self.last_indices, 0, sizeof(self.last_indices)) - nb_elements = find_objects(self, elements) for element_idx in xrange(nb_elements): element = <object>self.elements[element_idx] sprite = element.sprite ox, oy = element.x, element.y key, (vertices, uvs, colors) = get_sprite_rendering_data(sprite) - blendfunc = key // MAX_TEXTURES - texture = key % MAX_TEXTURES + blendfunc = key & 1 + texture = key >> 1 - rec = self.indices[blendfunc][texture] + rec = self.indices[texture][blendfunc] next_indice = self.last_indices[key] # Pack data in buffer @@ -142,9 +135,6 @@ cdef class Renderer: nb_vertices += 4 - if nb_vertices == 0: - return - if self.use_fixed_pipeline: glVertexPointer(3, GL_INT, sizeof(Vertex), &self.vertex_buffer[0].x) glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &self.vertex_buffer[0].u) @@ -161,23 +151,34 @@ cdef class Renderer: glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, True, sizeof(Vertex), <void*>20) glEnableVertexAttribArray(2) + # Don’t change the state when it’s not needed. + previous_blendfunc = -1 + previous_texture = -1 + for key in xrange(2 * MAX_TEXTURES): nb_indices = self.last_indices[key] if not nb_indices: continue - blendfunc = key // MAX_TEXTURES - texture = key % MAX_TEXTURES + blendfunc = key & 1 + texture = key >> 1 - glBlendFunc(GL_SRC_ALPHA, (GL_ONE_MINUS_SRC_ALPHA, GL_ONE)[blendfunc]) - glBindTexture(GL_TEXTURE_2D, texture) - glDrawElements(GL_TRIANGLES, nb_indices, GL_UNSIGNED_SHORT, self.indices[blendfunc][texture]) + if blendfunc != previous_blendfunc: + glBlendFunc(GL_SRC_ALPHA, (GL_ONE_MINUS_SRC_ALPHA, GL_ONE)[blendfunc]) + if texture != previous_texture: + glBindTexture(GL_TEXTURE_2D, texture) + glDrawElements(GL_TRIANGLES, nb_indices, GL_UNSIGNED_SHORT, self.indices[texture][blendfunc]) + + previous_blendfunc = blendfunc + previous_texture = texture + + glBindTexture(GL_TEXTURE_2D, 0) if not self.use_fixed_pipeline: glBindBuffer(GL_ARRAY_BUFFER, 0) - cdef void render_quads(self, rects, colors, texture): + cdef void render_quads(self, rects, colors, GLuint texture): # There is nothing that batch more than two quads on the same texture, currently. cdef Vertex buf[8] cdef unsigned short indices[12]