changeset 585:e0166cda75d5

Use primitive-restart to lower the size of our ibo, if supported.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Wed, 08 Oct 2014 14:28:37 +0200
parents 538b52aafbca
children 4b0593da29d5
files pytouhou/lib/opengl.pxd pytouhou/ui/opengl/backend.pxd pytouhou/ui/opengl/backend.pyx pytouhou/ui/opengl/background.pyx pytouhou/ui/opengl/renderer.pyx
diffstat 5 files changed, 53 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- 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)
--- 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
--- 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()
 
--- 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
--- 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