# HG changeset patch # User Emmanuel Gil Peyrot # Date 1412534286 -7200 # Node ID 47cf4e3d159dac500f51fbf655348a32a0e009f1 # Parent 6e79756b7f42af44326197c8a00e10ac6b6f6974 Use libepoxy to discover the actual GL version we are using, and available extensions. diff --git a/pytouhou/lib/opengl.pxd b/pytouhou/lib/opengl.pxd --- 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() 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 @@ -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 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 @@ -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")