changeset 583:47cf4e3d159d

Use libepoxy to discover the actual GL version we are using, and available extensions.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Sun, 05 Oct 2014 20:38:06 +0200
parents 6e79756b7f42
children 538b52aafbca
files pytouhou/lib/opengl.pxd pytouhou/ui/opengl/backend.pxd pytouhou/ui/opengl/backend.pyx
diffstat 3 files changed, 56 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/pytouhou/lib/opengl.pxd
+++ b/pytouhou/lib/opengl.pxd
@@ -169,3 +169,9 @@ cdef extern from 'epoxy/gl.h' nogil:
 
     void glPushDebugGroup(GLenum source, GLuint id_, GLsizei length, const char *message)
     void glPopDebugGroup()
+
+    # Non-OpenGL libepoxy functions.
+
+    int epoxy_gl_version()
+    bint epoxy_has_gl_extension(const char *extension)
+    bint epoxy_is_desktop_gl()
--- a/pytouhou/ui/opengl/backend.pxd
+++ b/pytouhou/ui/opengl/backend.pxd
@@ -1,7 +1,6 @@
 from pytouhou.lib.sdl cimport SDL_GLprofile
 
-cdef SDL_GLprofile flavor
-cdef str version
+cdef SDL_GLprofile profile
 cdef int major
 cdef int minor
 cdef int double_buffer
--- a/pytouhou/ui/opengl/backend.pyx
+++ b/pytouhou/ui/opengl/backend.pyx
@@ -5,20 +5,26 @@ from pytouhou.lib.opengl cimport \
          (glEnable, glHint, glEnableClientState, GL_TEXTURE_2D, GL_BLEND,
           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)
+          glPushDebugGroup, GL_DEBUG_SOURCE_APPLICATION, glPopDebugGroup,
+          epoxy_gl_version, epoxy_is_desktop_gl, epoxy_has_gl_extension)
 
 
 GameRenderer = None
 
 
 def init(options):
-    global flavor, version, major, minor, double_buffer, is_legacy, use_debug_group, use_vao, shader_header, GameRenderer
+    '''
+    Initialize the OpenGL module, and raise if something bad prevents it from
+    working.
+    '''
 
-    flavor_name = options['flavor']
-    assert flavor_name in ('core', 'es', 'compatibility', 'legacy')
-    flavor = (sdl.GL_CONTEXT_PROFILE_CORE if flavor_name == 'core' else
-              sdl.GL_CONTEXT_PROFILE_ES if flavor_name == 'es' else
-              sdl.GL_CONTEXT_PROFILE_COMPATIBILITY)
+    global profile, major, minor, double_buffer, is_legacy, GameRenderer
+
+    flavor = options['flavor']
+    assert flavor in ('core', 'es', 'compatibility', 'legacy')
+    profile = (sdl.GL_CONTEXT_PROFILE_CORE if flavor == 'core' else
+               sdl.GL_CONTEXT_PROFILE_ES if flavor == 'es' else
+               sdl.GL_CONTEXT_PROFILE_COMPATIBILITY)
 
     version = str(options['version'])
     assert len(version) == 3 and version[1] == '.'
@@ -27,30 +33,48 @@ def init(options):
 
     maybe_double_buffer = options['double-buffer']
     double_buffer = maybe_double_buffer if maybe_double_buffer is not None else -1
-    use_debug_group = (major == 4 and minor >= 3) or major > 4
-    use_vao = (major == 3 and minor >= 1) or major > 3
 
-    is_legacy = flavor_name == 'legacy'
-    is_gles = flavor_name == 'es'
-
-    if not is_gles:
-        try:
-            glsl_version = {'2.0': 110, '2.1': 120, '3.0': 130, '3.1': 140, '3.2': 150}[version]
-        except KeyError:
-            assert (major == 3 and minor == 3) or major > 3
-            glsl_version = 100 * major + 10 * minor
-        shader_header = '#version %d\n' % glsl_version
-    else:
-        glsl_version = {'2.0': 100, '3.0': 300}[version]
-        shader_header = '#version %d\n\nprecision highp float;\n' % glsl_version
+    is_legacy = flavor == 'legacy'
+    is_gles = flavor == 'es'
 
     #TODO: check for framebuffer/renderbuffer support.
 
     from pytouhou.ui.opengl.gamerenderer import GameRenderer
 
 
+def discover_features():
+    '''Discover which features are supported by our context.'''
+
+    global use_debug_group, use_vao, 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')
+
+    if is_desktop:
+        # gl_FragColor isn’t supported anymore starting with GLSL 4.2.
+        if version >= 42:
+            version = 41
+        try:
+            glsl_version = {20: 110, 21: 120, 30: 130, 31: 140, 32: 150}[version]
+        except KeyError:
+            assert version >= 33
+            glsl_version = version * 10
+        shader_header = '#version %d\n\n' % glsl_version
+    else:
+        # The attribute keyword isn’t supported past GLSL ES 3.0.
+        if version >= 30:
+            version = 20
+        glsl_version = {20: '100', 30: '300 es'}[version]
+        shader_header = '#version %s\n\nprecision highp float;\n\n' % glsl_version
+
+
 def create_window(title, x, y, width, height):
-    sdl.gl_set_attribute(sdl.GL_CONTEXT_PROFILE_MASK, flavor)
+    '''Create a window (using SDL) and an OpenGL context.'''
+
+    sdl.gl_set_attribute(sdl.GL_CONTEXT_PROFILE_MASK, profile)
     sdl.gl_set_attribute(sdl.GL_CONTEXT_MAJOR_VERSION, major)
     sdl.gl_set_attribute(sdl.GL_CONTEXT_MINOR_VERSION, minor)
     sdl.gl_set_attribute(sdl.GL_DEPTH_SIZE, 24)
@@ -66,6 +90,8 @@ def create_window(title, x, y, width, he
     window = Window(title, x, y, width, height, flags)
     window.gl_create_context()
 
+    discover_features()
+
     if use_debug_group:
         glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, -1, "OpenGL initialisation")