comparison pytouhou/ui/opengl/backend.pyx @ 595:b7b4a234bf70

Fix legacy OpenGL support, and detect the absence of non-legacy context with libepoxy.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Sun, 19 Oct 2014 17:22:26 +0200
parents 974decb8df4f
children 23b9418e4b2f
comparison
equal deleted inserted replaced
594:12756994a92c 595:b7b4a234bf70
19 ''' 19 '''
20 Initialize the OpenGL module, and raise if something bad prevents it from 20 Initialize the OpenGL module, and raise if something bad prevents it from
21 working. 21 working.
22 ''' 22 '''
23 23
24 cdef str flavor
25
24 global profile, major, minor, double_buffer, is_legacy, GameRenderer 26 global profile, major, minor, double_buffer, is_legacy, GameRenderer
25 27
26 flavor = options['flavor'] 28 flavor = options['flavor']
27 assert flavor in ('core', 'es', 'compatibility', 'legacy') 29 assert flavor in ('core', 'es', 'compatibility', 'legacy')
28 profile = (sdl.GL_CONTEXT_PROFILE_CORE if flavor == 'core' else 30 profile = (sdl.GL_CONTEXT_PROFILE_CORE if flavor == 'core' else
35 minor = int(version[2]) 37 minor = int(version[2])
36 38
37 maybe_double_buffer = options['double-buffer'] 39 maybe_double_buffer = options['double-buffer']
38 double_buffer = maybe_double_buffer if maybe_double_buffer is not None else -1 40 double_buffer = maybe_double_buffer if maybe_double_buffer is not None else -1
39 41
40 is_legacy = flavor == 'legacy' 42 is_legacy = flavor == 'legacy' or flavor == 'compatibility' and major < 2
41 is_gles = flavor == 'es'
42 43
43 #TODO: check for framebuffer/renderbuffer support. 44 #TODO: check for framebuffer/renderbuffer support.
44 45
45 from pytouhou.ui.opengl.gamerenderer import GameRenderer 46 from pytouhou.ui.opengl.gamerenderer import GameRenderer
46 47
47 48
48 def discover_features(): 49 cdef void discover_features() except *:
49 '''Discover which features are supported by our context.''' 50 '''Discover which features are supported by our context.'''
50 51
51 global use_debug_group, use_vao, use_primitive_restart, use_pack_invert 52 global use_debug_group, use_vao, use_primitive_restart, use_framebuffer_blit, use_pack_invert
52 global primitive_mode 53 global primitive_mode
53 global shader_header 54 global shader_header
55 global is_legacy
54 56
55 version = epoxy_gl_version() 57 version = epoxy_gl_version()
56 is_desktop = epoxy_is_desktop_gl() 58 is_desktop = epoxy_is_desktop_gl()
59 is_legacy = is_desktop and version < 20
57 60
58 use_debug_group = (is_desktop and version >= 43) or epoxy_has_gl_extension('GL_KHR_debug') 61 use_debug_group = (is_desktop and version >= 43) or epoxy_has_gl_extension('GL_KHR_debug')
59 use_vao = (is_desktop and version >= 30) or epoxy_has_gl_extension('GL_ARB_vertex_array_object') 62 use_vao = (is_desktop and version >= 30) or epoxy_has_gl_extension('GL_ARB_vertex_array_object')
60 use_primitive_restart = (is_desktop and version >= 31) 63 use_primitive_restart = (is_desktop and version >= 31)
61 use_framebuffer_blit = (is_desktop and version >= 30) 64 use_framebuffer_blit = (is_desktop and version >= 30)
62 use_pack_invert = epoxy_has_gl_extension('GL_MESA_pack_invert') 65 use_pack_invert = epoxy_has_gl_extension('GL_MESA_pack_invert')
63 66
64 primitive_mode = GL_TRIANGLE_STRIP if use_primitive_restart else GL_TRIANGLES 67 primitive_mode = GL_TRIANGLE_STRIP if use_primitive_restart else GL_TRIANGLES
65 68
66 if is_desktop: 69 if not is_legacy:
67 # gl_FragColor isn’t supported anymore starting with GLSL 4.2. 70 if is_desktop:
68 if version >= 42: 71 # gl_FragColor isn’t supported anymore starting with GLSL 4.2.
69 version = 41 72 if version >= 42:
70 try: 73 version = 41
71 glsl_version = {20: 110, 21: 120, 30: 130, 31: 140, 32: 150}[version] 74 try:
72 except KeyError: 75 glsl_version = {20: 110, 21: 120, 30: 130, 31: 140, 32: 150}[version]
73 assert version >= 33 76 except KeyError:
74 glsl_version = version * 10 77 assert version >= 33
75 shader_header = ('#version %d\n\n' % glsl_version).encode() 78 glsl_version = version * 10
76 else: 79 shader_header = ('#version %d\n\n' % glsl_version).encode()
77 # The attribute keyword isn’t supported past GLSL ES 3.0. 80 else:
78 if version >= 30: 81 # The attribute keyword isn’t supported past GLSL ES 3.0.
79 version = 20 82 if version >= 30:
80 glsl_version = {20: '100', 30: '300 es'}[version] 83 version = 20
81 shader_header = ('#version %s\n\nprecision highp float;\n\n' % glsl_version).encode() 84 glsl_version = {20: '100', 30: '300 es'}[version]
85 shader_header = ('#version %s\n\nprecision highp float;\n\n' % glsl_version).encode()
82 86
83 87
84 def create_window(title, x, y, width, height, swap_interval): 88 def create_window(title, x, y, width, height, swap_interval):
85 '''Create a window (using SDL) and an OpenGL context.''' 89 '''Create a window (using SDL) and an OpenGL context.'''
86 90
90 sdl.gl_set_attribute(sdl.GL_DEPTH_SIZE, 24) 94 sdl.gl_set_attribute(sdl.GL_DEPTH_SIZE, 24)
91 if double_buffer >= 0: 95 if double_buffer >= 0:
92 sdl.gl_set_attribute(sdl.GL_DOUBLEBUFFER, double_buffer) 96 sdl.gl_set_attribute(sdl.GL_DOUBLEBUFFER, double_buffer)
93 97
94 flags = sdl.WINDOW_SHOWN | sdl.WINDOW_OPENGL 98 flags = sdl.WINDOW_SHOWN | sdl.WINDOW_OPENGL
95
96 #TODO: legacy can support one of the framebuffer extensions.
97 if not is_legacy: 99 if not is_legacy:
98 flags |= sdl.WINDOW_RESIZABLE 100 flags |= sdl.WINDOW_RESIZABLE
99 101
100 window = Window(title, x, y, width, height, flags) 102 window = Window(title, x, y, width, height, flags)
101 window.gl_create_context() 103 window.gl_create_context()
102 104
103 discover_features() 105 discover_features()
106
107 #TODO: legacy could support one of the framebuffer extensions for resize,
108 # but for now set the window to a fixed size.
109 if is_legacy and flags & sdl.WINDOW_RESIZABLE:
110 flags &= ~sdl.WINDOW_RESIZABLE
111 window = Window(title, x, y, width, height, flags)
112 window.gl_create_context()
104 113
105 if use_debug_group: 114 if use_debug_group:
106 glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, -1, "OpenGL initialisation") 115 glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, -1, "OpenGL initialisation")
107 116
108 # Initialize OpenGL 117 # Initialize OpenGL
127 136
128 if swap_interval is not None: 137 if swap_interval is not None:
129 try: 138 try:
130 sdl.gl_set_swap_interval(swap_interval) 139 sdl.gl_set_swap_interval(swap_interval)
131 except sdl.SDLError: 140 except sdl.SDLError:
141 # The OpenGL context doesn’t support setting the swap interval,
142 # we’ll probably fallback to SDL_Delay-based clocking.
132 pass 143 pass
133 144
134 return window 145 return window