# HG changeset patch # User Emmanuel Gil Peyrot # Date 1412771317 -7200 # Node ID e0166cda75d50efc90bdb234ed341391520c27f6 # Parent 538b52aafbca03913d1973cb44ab5d7236bbadba Use primitive-restart to lower the size of our ibo, if supported. diff --git a/pytouhou/lib/opengl.pxd b/pytouhou/lib/opengl.pxd --- a/pytouhou/lib/opengl.pxd +++ b/pytouhou/lib/opengl.pxd @@ -80,6 +80,7 @@ cdef extern from 'epoxy/gl.h' nogil: ctypedef enum GLenum_mode 'GLenum': GL_TRIANGLES + GL_TRIANGLE_STRIP ctypedef enum GLenum_buffer 'GLenum': GL_ARRAY_BUFFER @@ -124,6 +125,7 @@ cdef extern from 'epoxy/gl.h' nogil: GL_LINEAR GL_SCISSOR_TEST GL_FOG + GL_PRIMITIVE_RESTART void glVertexPointer(GLint size, GLenum_type type_, GLsizei stride, GLvoid *pointer) void glTexCoordPointer(GLint size, GLenum_type type_, GLsizei stride, GLvoid *pointer) @@ -197,6 +199,8 @@ cdef extern from 'epoxy/gl.h' nogil: void glDeleteVertexArrays(GLsizei n, const GLuint *arrays) void glBindVertexArray(GLuint array) + void glPrimitiveRestartIndex(GLuint index) + # Debug void glPushDebugGroup(GLenum_debug source, GLuint id_, GLsizei length, const char *message) diff --git a/pytouhou/ui/opengl/backend.pxd b/pytouhou/ui/opengl/backend.pxd --- a/pytouhou/ui/opengl/backend.pxd +++ b/pytouhou/ui/opengl/backend.pxd @@ -7,4 +7,5 @@ cdef int double_buffer cdef bint is_legacy cdef bint use_debug_group cdef bint use_vao +cdef bint use_primitive_restart cdef str shader_header diff --git a/pytouhou/ui/opengl/backend.pyx b/pytouhou/ui/opengl/backend.pyx --- a/pytouhou/ui/opengl/backend.pyx +++ b/pytouhou/ui/opengl/backend.pyx @@ -6,7 +6,8 @@ from pytouhou.lib.opengl cimport \ GL_PERSPECTIVE_CORRECTION_HINT, GL_FOG_HINT, GL_NICEST, GL_COLOR_ARRAY, GL_VERTEX_ARRAY, GL_TEXTURE_COORD_ARRAY, glPushDebugGroup, GL_DEBUG_SOURCE_APPLICATION, glPopDebugGroup, - epoxy_gl_version, epoxy_is_desktop_gl, epoxy_has_gl_extension) + epoxy_gl_version, epoxy_is_desktop_gl, epoxy_has_gl_extension, + GL_PRIMITIVE_RESTART, glPrimitiveRestartIndex) GameRenderer = None @@ -45,13 +46,14 @@ def init(options): def discover_features(): '''Discover which features are supported by our context.''' - global use_debug_group, use_vao, shader_header + global use_debug_group, use_vao, use_primitive_restart, shader_header version = epoxy_gl_version() is_desktop = epoxy_is_desktop_gl() use_debug_group = (is_desktop and version >= 43) or epoxy_has_gl_extension('GL_KHR_debug') use_vao = (is_desktop and version >= 30) or epoxy_has_gl_extension('GL_ARB_vertex_array_object') + use_primitive_restart = (is_desktop and version >= 31) if is_desktop: # gl_FragColor isn’t supported anymore starting with GLSL 4.2. @@ -105,6 +107,10 @@ def create_window(title, x, y, width, he glEnableClientState(GL_VERTEX_ARRAY) glEnableClientState(GL_TEXTURE_COORD_ARRAY) + if use_primitive_restart: + glEnable(GL_PRIMITIVE_RESTART) + glPrimitiveRestartIndex(0xFFFF); + if use_debug_group: glPopDebugGroup() diff --git a/pytouhou/ui/opengl/background.pyx b/pytouhou/ui/opengl/background.pyx --- a/pytouhou/ui/opengl/background.pyx +++ b/pytouhou/ui/opengl/background.pyx @@ -23,10 +23,11 @@ from pytouhou.lib.opengl cimport \ glDisable, GL_DEPTH_TEST, glDrawElements, GL_TRIANGLES, GL_UNSIGNED_SHORT, GL_ELEMENT_ARRAY_BUFFER, glDeleteBuffers, glGenVertexArrays, glDeleteVertexArrays, glBindVertexArray, - glPushDebugGroup, GL_DEBUG_SOURCE_APPLICATION, glPopDebugGroup) + glPushDebugGroup, GL_DEBUG_SOURCE_APPLICATION, glPopDebugGroup, + GL_TRIANGLE_STRIP) from .sprite cimport get_sprite_rendering_data -from .backend cimport is_legacy, use_debug_group, use_vao +from .backend cimport is_legacy, use_debug_group, use_vao, use_primitive_restart cdef class BackgroundRenderer: @@ -94,7 +95,7 @@ cdef class BackgroundRenderer: glEnable(GL_DEPTH_TEST) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glBindTexture(GL_TEXTURE_2D, self.texture) - glDrawElements(GL_TRIANGLES, self.nb_indices, GL_UNSIGNED_SHORT, indices) + glDrawElements(GL_TRIANGLE_STRIP if use_primitive_restart else GL_TRIANGLES, self.nb_indices, GL_UNSIGNED_SHORT, indices) glDisable(GL_DEPTH_TEST) if not is_legacy: @@ -127,19 +128,26 @@ cdef class BackgroundRenderer: # Pack data vertex_buffer[nb_vertices] = Vertex(x1 + ox + ox2, y1 + oy + oy2, z1 + oz + oz2, data.left, data.bottom, r, g, b, a) vertex_buffer[nb_vertices+1] = Vertex(x2 + ox + ox2, y2 + oy + oy2, z2 + oz + oz2, data.right, data.bottom, r, g, b, a) - vertex_buffer[nb_vertices+2] = Vertex(x3 + ox + ox2, y3 + oy + oy2, z3 + oz + oz2, data.right, data.top, r, g, b, a) - vertex_buffer[nb_vertices+3] = Vertex(x4 + ox + ox2, y4 + oy + oy2, z4 + oz + oz2, data.left, data.top, r, g, b, a) + vertex_buffer[nb_vertices+2] = Vertex(x4 + ox + ox2, y4 + oy + oy2, z4 + oz + oz2, data.left, data.top, r, g, b, a) + vertex_buffer[nb_vertices+3] = Vertex(x3 + ox + ox2, y3 + oy + oy2, z3 + oz + oz2, data.right, data.top, r, g, b, a) # Add indices - indices[nb_indices] = nb_vertices - indices[nb_indices+1] = nb_vertices + 1 - indices[nb_indices+2] = nb_vertices + 2 - indices[nb_indices+3] = nb_vertices + 2 - indices[nb_indices+4] = nb_vertices + 3 - indices[nb_indices+5] = nb_vertices + if use_primitive_restart: + indices[nb_indices] = nb_vertices + indices[nb_indices+1] = nb_vertices + 1 + indices[nb_indices+2] = nb_vertices + 2 + indices[nb_indices+3] = nb_vertices + 3 + indices[nb_indices+4] = 0xFFFF + else: + indices[nb_indices] = nb_vertices + indices[nb_indices+1] = nb_vertices + 1 + indices[nb_indices+2] = nb_vertices + 2 + indices[nb_indices+3] = nb_vertices + 1 + indices[nb_indices+4] = nb_vertices + 2 + indices[nb_indices+5] = nb_vertices + 3 nb_vertices += 4 - nb_indices += 6 + nb_indices += 5 if use_primitive_restart else 6 # We only need to keep the rendered vertices and indices in memory, # either in RAM or in VRAM, they will never change until we implement diff --git a/pytouhou/ui/opengl/renderer.pyx b/pytouhou/ui/opengl/renderer.pyx --- a/pytouhou/ui/opengl/renderer.pyx +++ b/pytouhou/ui/opengl/renderer.pyx @@ -34,13 +34,13 @@ from pytouhou.lib.opengl cimport \ GL_DEPTH_BUFFER_BIT, GLuint, glDeleteTextures, GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, glGenVertexArrays, glDeleteVertexArrays, glBindVertexArray, glPushDebugGroup, - GL_DEBUG_SOURCE_APPLICATION, glPopDebugGroup) + GL_DEBUG_SOURCE_APPLICATION, glPopDebugGroup, GL_TRIANGLE_STRIP) from pytouhou.lib.sdl import SDLError from pytouhou.game.element cimport Element from .sprite cimport get_sprite_rendering_data -from .backend cimport is_legacy, use_debug_group, use_vao +from .backend cimport is_legacy, use_debug_group, use_vao, use_primitive_restart from pytouhou.utils.helpers import get_logger @@ -197,17 +197,25 @@ cdef class Renderer: r, g, b, a = data.color[0], data.color[1], data.color[2], data.color[3] self.vertex_buffer[nb_vertices] = Vertex(x1 + ox, y1 + oy, z1, 0, data.left, data.bottom, r, g, b, a) self.vertex_buffer[nb_vertices+1] = Vertex(x2 + ox, y2 + oy, z2, 0, data.right, data.bottom, r, g, b, a) - self.vertex_buffer[nb_vertices+2] = Vertex(x3 + ox, y3 + oy, z3, 0, data.right, data.top, r, g, b, a) - self.vertex_buffer[nb_vertices+3] = Vertex(x4 + ox, y4 + oy, z4, 0, data.left, data.top, r, g, b, a) + self.vertex_buffer[nb_vertices+2] = Vertex(x4 + ox, y4 + oy, z4, 0, data.left, data.top, r, g, b, a) + self.vertex_buffer[nb_vertices+3] = Vertex(x3 + ox, y3 + oy, z3, 0, data.right, data.top, r, g, b, a) # Add indices - rec[next_indice] = nb_vertices - rec[next_indice+1] = nb_vertices + 1 - rec[next_indice+2] = nb_vertices + 2 - rec[next_indice+3] = nb_vertices + 2 - rec[next_indice+4] = nb_vertices + 3 - rec[next_indice+5] = nb_vertices - self.last_indices[key] += 6 + if use_primitive_restart: + rec[next_indice] = nb_vertices + rec[next_indice+1] = nb_vertices + 1 + rec[next_indice+2] = nb_vertices + 2 + rec[next_indice+3] = nb_vertices + 3 + rec[next_indice+4] = 0xFFFF + self.last_indices[key] += 5 + else: + rec[next_indice] = nb_vertices + rec[next_indice+1] = nb_vertices + 1 + rec[next_indice+2] = nb_vertices + 2 + rec[next_indice+3] = nb_vertices + 1 + rec[next_indice+4] = nb_vertices + 2 + rec[next_indice+5] = nb_vertices + 3 + self.last_indices[key] += 6 nb_vertices += 4 @@ -244,7 +252,7 @@ cdef class Renderer: glBlendFunc(GL_SRC_ALPHA, (GL_ONE_MINUS_SRC_ALPHA, GL_ONE)[blendfunc]) if texture != previous_texture: glBindTexture(GL_TEXTURE_2D, self.textures[texture]) - glDrawElements(GL_TRIANGLES, nb_indices, GL_UNSIGNED_SHORT, self.indices[texture][blendfunc]) + glDrawElements(GL_TRIANGLE_STRIP if use_primitive_restart else GL_TRIANGLES, nb_indices, GL_UNSIGNED_SHORT, self.indices[texture][blendfunc]) previous_blendfunc = blendfunc previous_texture = texture