0
# OpenGL Context
1
2
OpenGL context creation, management, buffer swapping, and OpenGL function loading for hardware-accelerated graphics rendering.
3
4
## Capabilities
5
6
### Context Management
7
8
Control the current OpenGL context and manage context switching between windows.
9
10
```python { .api }
11
def make_context_current(window) -> None:
12
"""
13
Make the OpenGL context of the specified window current for the calling thread.
14
15
A context must be current before any OpenGL functions are called.
16
17
Parameters:
18
window: Window whose context to make current, or None to detach current context
19
"""
20
21
def get_current_context():
22
"""
23
Get the window whose context is current on the calling thread.
24
25
Returns:
26
GLFWwindow: Window with current context, or None if no context is current
27
"""
28
```
29
30
### Buffer Swapping
31
32
Manage front and back buffer swapping for double-buffered rendering.
33
34
```python { .api }
35
def swap_buffers(window) -> None:
36
"""
37
Swap the front and back buffers of the specified window.
38
39
This function swaps the front and back buffers of the specified window
40
when rendering with OpenGL. If the swap interval is greater than zero,
41
the GPU driver waits the specified number of screen updates before swapping the buffers.
42
43
Parameters:
44
window: Window whose buffers to swap
45
"""
46
47
def swap_interval(interval: int) -> None:
48
"""
49
Set the swap interval for the current OpenGL context.
50
51
The swap interval is the minimum number of screen updates to wait
52
from the time swap_buffers was called before swapping the buffers
53
and returning.
54
55
Parameters:
56
interval: Minimum number of screen updates to wait (0 = no wait, 1 = vsync)
57
"""
58
```
59
60
### OpenGL Function Loading
61
62
Load OpenGL functions and query extension support.
63
64
```python { .api }
65
def extension_supported(extension: str) -> int:
66
"""
67
Check whether the specified OpenGL or WGL/GLX extension is available.
68
69
Parameters:
70
extension: ASCII encoded name of the extension
71
72
Returns:
73
int: 1 if extension is available, 0 otherwise
74
"""
75
76
def get_proc_address(procname: str) -> ctypes.c_void_p:
77
"""
78
Get the address of the specified OpenGL function for the current context.
79
80
This function returns the address of the specified OpenGL or
81
OpenGL ES core or extension function, if it is supported by the current context.
82
83
Parameters:
84
procname: ASCII encoded name of the function
85
86
Returns:
87
ctypes.c_void_p: Function address, or None if function is not available
88
"""
89
```
90
91
### Context Creation Hints
92
93
Configure OpenGL context properties before window creation.
94
95
#### Context API Constants
96
97
```python { .api }
98
# Client API selection
99
CLIENT_API: int = 0x00022001
100
NO_API: int = 0
101
OPENGL_API: int = 0x00030001
102
OPENGL_ES_API: int = 0x00030002
103
104
# OpenGL profile selection
105
OPENGL_PROFILE: int = 0x00022008
106
OPENGL_ANY_PROFILE: int = 0
107
OPENGL_CORE_PROFILE: int = 0x00032001
108
OPENGL_COMPAT_PROFILE: int = 0x00032002
109
110
# Context version
111
CONTEXT_VERSION_MAJOR: int = 0x00022002
112
CONTEXT_VERSION_MINOR: int = 0x00022003
113
CONTEXT_REVISION: int = 0x00022004
114
115
# Context flags
116
OPENGL_FORWARD_COMPAT: int = 0x00022006
117
OPENGL_DEBUG_CONTEXT: int = 0x00022007
118
CONTEXT_DEBUG: int = 0x00022007
119
CONTEXT_NO_ERROR: int = 0x0002200A
120
121
# Context robustness
122
CONTEXT_ROBUSTNESS: int = 0x00022005
123
NO_ROBUSTNESS: int = 0
124
NO_RESET_NOTIFICATION: int = 0x00031001
125
LOSE_CONTEXT_ON_RESET: int = 0x00031002
126
127
# Context release behavior
128
CONTEXT_RELEASE_BEHAVIOR: int = 0x00022009
129
ANY_RELEASE_BEHAVIOR: int = 0
130
RELEASE_BEHAVIOR_FLUSH: int = 0x00035001
131
RELEASE_BEHAVIOR_NONE: int = 0x00035002
132
133
# Context creation API
134
CONTEXT_CREATION_API: int = 0x0002200B
135
NATIVE_CONTEXT_API: int = 0x00036001
136
EGL_CONTEXT_API: int = 0x00036002
137
OSMESA_CONTEXT_API: int = 0x00036003
138
```
139
140
### Time Functions
141
142
Get precise timing information for animation and frame rate control.
143
144
```python { .api }
145
def get_time() -> float:
146
"""
147
Get the current value of the GLFW timer.
148
149
The timer measures time elapsed since GLFW was initialized,
150
unless the timer has been set using set_time.
151
152
Returns:
153
float: Current time, in seconds
154
"""
155
156
def set_time(time: float) -> None:
157
"""
158
Set the GLFW timer to the specified value.
159
160
Parameters:
161
time: New value, in seconds
162
"""
163
164
def get_timer_value() -> int:
165
"""
166
Get the current value of the raw timer.
167
168
This function returns the current value of the raw timer,
169
measured in 1 / frequency seconds.
170
171
Returns:
172
int: Raw timer value
173
"""
174
175
def get_timer_frequency() -> int:
176
"""
177
Get the frequency, in Hz, of the raw timer.
178
179
Returns:
180
int: Timer frequency in Hz
181
"""
182
```
183
184
## Platform-Specific Functions
185
186
Access platform-specific OpenGL context handles and properties.
187
188
### Windows (WGL)
189
190
```python { .api }
191
def get_wgl_context(window) -> ctypes.c_void_p:
192
"""
193
Get the HGLRC of the specified window.
194
195
Parameters:
196
window: Window handle
197
198
Returns:
199
ctypes.c_void_p: WGL context handle (HGLRC)
200
"""
201
```
202
203
### macOS (NSGL)
204
205
```python { .api }
206
def get_nsgl_context(window) -> ctypes.c_void_p:
207
"""
208
Get the NSOpenGLContext of the specified window.
209
210
Parameters:
211
window: Window handle
212
213
Returns:
214
ctypes.c_void_p: NSGL context handle (NSOpenGLContext)
215
"""
216
```
217
218
### X11 (GLX)
219
220
```python { .api }
221
def get_glx_context(window) -> ctypes.c_void_p:
222
"""
223
Get the GLXContext of the specified window.
224
225
Parameters:
226
window: Window handle
227
228
Returns:
229
ctypes.c_void_p: GLX context handle (GLXContext)
230
"""
231
232
def get_glx_window(window) -> int:
233
"""
234
Get the GLXWindow of the specified window.
235
236
Parameters:
237
window: Window handle
238
239
Returns:
240
int: GLX window identifier (GLXWindow)
241
"""
242
```
243
244
### EGL
245
246
```python { .api }
247
def get_egl_display() -> ctypes.c_void_p:
248
"""
249
Get the EGLDisplay used by GLFW.
250
251
Returns:
252
ctypes.c_void_p: EGL display handle (EGLDisplay)
253
"""
254
255
def get_egl_context(window) -> ctypes.c_void_p:
256
"""
257
Get the EGLContext of the specified window.
258
259
Parameters:
260
window: Window handle
261
262
Returns:
263
ctypes.c_void_p: EGL context handle (EGLContext)
264
"""
265
266
def get_egl_surface(window) -> ctypes.c_void_p:
267
"""
268
Get the EGLSurface of the specified window.
269
270
Parameters:
271
window: Window handle
272
273
Returns:
274
ctypes.c_void_p: EGL surface handle (EGLSurface)
275
"""
276
```
277
278
### OSMesa (Off-Screen Mesa)
279
280
```python { .api }
281
def get_os_mesa_context(window) -> ctypes.c_void_p:
282
"""
283
Get the OSMesaContext of the specified window.
284
285
Parameters:
286
window: Window handle
287
288
Returns:
289
ctypes.c_void_p: OSMesa context handle (OSMesaContext)
290
"""
291
292
def get_os_mesa_color_buffer(window) -> tuple:
293
"""
294
Get the color buffer associated with the specified window.
295
296
Parameters:
297
window: Window handle
298
299
Returns:
300
tuple: (width, height, format, buffer) or None if failed
301
"""
302
303
def get_os_mesa_depth_buffer(window) -> tuple:
304
"""
305
Get the depth buffer associated with the specified window.
306
307
Parameters:
308
window: Window handle
309
310
Returns:
311
tuple: (width, height, bytes_per_value, buffer) or None if failed
312
"""
313
```
314
315
## Usage Examples
316
317
### Basic OpenGL Setup
318
319
```python
320
import glfw
321
322
# Initialize GLFW
323
glfw.init()
324
325
# Request specific OpenGL version (3.3 Core)
326
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
327
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
328
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
329
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, glfw.TRUE) # macOS
330
331
# Create window with OpenGL context
332
window = glfw.create_window(800, 600, "OpenGL Context", None, None)
333
if not window:
334
glfw.terminate()
335
raise Exception("Failed to create window")
336
337
# Make the context current
338
glfw.make_context_current(window)
339
340
# Enable v-sync
341
glfw.swap_interval(1)
342
343
# Main render loop
344
while not glfw.window_should_close(window):
345
glfw.poll_events()
346
347
# OpenGL rendering commands go here
348
# glClear, glDrawArrays, etc.
349
350
# Swap front and back buffers
351
glfw.swap_buffers(window)
352
353
glfw.terminate()
354
```
355
356
### OpenGL Function Loading
357
358
```python
359
import glfw
360
import ctypes
361
362
glfw.init()
363
364
# Create context first
365
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
366
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
367
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
368
369
window = glfw.create_window(800, 600, "Function Loading", None, None)
370
glfw.make_context_current(window)
371
372
# Check for extensions
373
if glfw.extension_supported("GL_ARB_vertex_array_object"):
374
print("VAO extension supported")
375
376
# Load OpenGL functions
377
gl_clear = glfw.get_proc_address("glClear")
378
gl_clear_color = glfw.get_proc_address("glClearColor")
379
380
if gl_clear and gl_clear_color:
381
print("Successfully loaded OpenGL functions")
382
383
# Convert to callable Python functions
384
glClear = ctypes.CFUNCTYPE(None, ctypes.c_uint)(gl_clear)
385
glClearColor = ctypes.CFUNCTYPE(None, ctypes.c_float, ctypes.c_float,
386
ctypes.c_float, ctypes.c_float)(gl_clear_color)
387
388
# Use the functions
389
glClearColor(0.2, 0.3, 0.3, 1.0)
390
glClear(0x00004000) # GL_COLOR_BUFFER_BIT
391
392
glfw.terminate()
393
```
394
395
### Context Sharing
396
397
```python
398
import glfw
399
400
glfw.init()
401
402
# Create main window
403
main_window = glfw.create_window(800, 600, "Main Window", None, None)
404
glfw.make_context_current(main_window)
405
406
# Load textures, create VAOs, etc. in main context
407
# ... OpenGL resource creation ...
408
409
# Create second window sharing the context
410
shared_window = glfw.create_window(400, 300, "Shared Context", None, main_window)
411
412
# Both windows can now access the same OpenGL resources
413
while not glfw.window_should_close(main_window) and not glfw.window_should_close(shared_window):
414
glfw.poll_events()
415
416
# Render to main window
417
glfw.make_context_current(main_window)
418
# ... render main window ...
419
glfw.swap_buffers(main_window)
420
421
# Render to shared window (can use same resources)
422
glfw.make_context_current(shared_window)
423
# ... render shared window ...
424
glfw.swap_buffers(shared_window)
425
426
glfw.terminate()
427
```
428
429
### Debug Context
430
431
```python
432
import glfw
433
434
def gl_debug_callback(source, type, id, severity, length, message, user_param):
435
print(f"OpenGL Debug: {message}")
436
437
glfw.init()
438
439
# Request debug context
440
glfw.window_hint(glfw.OPENGL_DEBUG_CONTEXT, glfw.TRUE)
441
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
442
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
443
444
window = glfw.create_window(800, 600, "Debug Context", None, None)
445
glfw.make_context_current(window)
446
447
# Check if debug context was created
448
if glfw.get_window_attrib(window, glfw.CONTEXT_DEBUG):
449
print("Debug context created successfully")
450
451
# Set up debug callback (would need OpenGL wrapper like PyOpenGL)
452
# gl.glDebugMessageCallback(gl_debug_callback, None)
453
# gl.glEnable(gl.GL_DEBUG_OUTPUT)
454
455
glfw.terminate()
456
```
457
458
### Frame Rate Control
459
460
```python
461
import glfw
462
import time
463
464
glfw.init()
465
window = glfw.create_window(800, 600, "Frame Rate", None, None)
466
glfw.make_context_current(window)
467
468
# Disable v-sync for manual frame rate control
469
glfw.swap_interval(0)
470
471
target_fps = 60
472
frame_time = 1.0 / target_fps
473
last_time = glfw.get_time()
474
frame_count = 0
475
476
while not glfw.window_should_close(window):
477
current_time = glfw.get_time()
478
delta_time = current_time - last_time
479
480
glfw.poll_events()
481
482
# Render frame
483
# ... OpenGL rendering ...
484
485
glfw.swap_buffers(window)
486
487
# Frame rate limiting
488
frame_time_used = glfw.get_time() - current_time
489
sleep_time = frame_time - frame_time_used
490
if sleep_time > 0:
491
time.sleep(sleep_time)
492
493
# FPS counter
494
frame_count += 1
495
if current_time - last_time >= 1.0:
496
fps = frame_count / (current_time - last_time)
497
glfw.set_window_title(window, f"Frame Rate - FPS: {fps:.1f}")
498
frame_count = 0
499
last_time = current_time
500
501
glfw.terminate()
502
```