A ctypes-based wrapper for GLFW3 that provides Python bindings for OpenGL, OpenGL ES, and Vulkan development on desktop platforms.
—
OpenGL context creation, management, buffer swapping, and OpenGL function loading for hardware-accelerated graphics rendering.
Control the current OpenGL context and manage context switching between windows.
def make_context_current(window) -> None:
"""
Make the OpenGL context of the specified window current for the calling thread.
A context must be current before any OpenGL functions are called.
Parameters:
window: Window whose context to make current, or None to detach current context
"""
def get_current_context():
"""
Get the window whose context is current on the calling thread.
Returns:
GLFWwindow: Window with current context, or None if no context is current
"""Manage front and back buffer swapping for double-buffered rendering.
def swap_buffers(window) -> None:
"""
Swap the front and back buffers of the specified window.
This function swaps the front and back buffers of the specified window
when rendering with OpenGL. If the swap interval is greater than zero,
the GPU driver waits the specified number of screen updates before swapping the buffers.
Parameters:
window: Window whose buffers to swap
"""
def swap_interval(interval: int) -> None:
"""
Set the swap interval for the current OpenGL context.
The swap interval is the minimum number of screen updates to wait
from the time swap_buffers was called before swapping the buffers
and returning.
Parameters:
interval: Minimum number of screen updates to wait (0 = no wait, 1 = vsync)
"""Load OpenGL functions and query extension support.
def extension_supported(extension: str) -> int:
"""
Check whether the specified OpenGL or WGL/GLX extension is available.
Parameters:
extension: ASCII encoded name of the extension
Returns:
int: 1 if extension is available, 0 otherwise
"""
def get_proc_address(procname: str) -> ctypes.c_void_p:
"""
Get the address of the specified OpenGL function for the current context.
This function returns the address of the specified OpenGL or
OpenGL ES core or extension function, if it is supported by the current context.
Parameters:
procname: ASCII encoded name of the function
Returns:
ctypes.c_void_p: Function address, or None if function is not available
"""Configure OpenGL context properties before window creation.
# Client API selection
CLIENT_API: int = 0x00022001
NO_API: int = 0
OPENGL_API: int = 0x00030001
OPENGL_ES_API: int = 0x00030002
# OpenGL profile selection
OPENGL_PROFILE: int = 0x00022008
OPENGL_ANY_PROFILE: int = 0
OPENGL_CORE_PROFILE: int = 0x00032001
OPENGL_COMPAT_PROFILE: int = 0x00032002
# Context version
CONTEXT_VERSION_MAJOR: int = 0x00022002
CONTEXT_VERSION_MINOR: int = 0x00022003
CONTEXT_REVISION: int = 0x00022004
# Context flags
OPENGL_FORWARD_COMPAT: int = 0x00022006
OPENGL_DEBUG_CONTEXT: int = 0x00022007
CONTEXT_DEBUG: int = 0x00022007
CONTEXT_NO_ERROR: int = 0x0002200A
# Context robustness
CONTEXT_ROBUSTNESS: int = 0x00022005
NO_ROBUSTNESS: int = 0
NO_RESET_NOTIFICATION: int = 0x00031001
LOSE_CONTEXT_ON_RESET: int = 0x00031002
# Context release behavior
CONTEXT_RELEASE_BEHAVIOR: int = 0x00022009
ANY_RELEASE_BEHAVIOR: int = 0
RELEASE_BEHAVIOR_FLUSH: int = 0x00035001
RELEASE_BEHAVIOR_NONE: int = 0x00035002
# Context creation API
CONTEXT_CREATION_API: int = 0x0002200B
NATIVE_CONTEXT_API: int = 0x00036001
EGL_CONTEXT_API: int = 0x00036002
OSMESA_CONTEXT_API: int = 0x00036003Get precise timing information for animation and frame rate control.
def get_time() -> float:
"""
Get the current value of the GLFW timer.
The timer measures time elapsed since GLFW was initialized,
unless the timer has been set using set_time.
Returns:
float: Current time, in seconds
"""
def set_time(time: float) -> None:
"""
Set the GLFW timer to the specified value.
Parameters:
time: New value, in seconds
"""
def get_timer_value() -> int:
"""
Get the current value of the raw timer.
This function returns the current value of the raw timer,
measured in 1 / frequency seconds.
Returns:
int: Raw timer value
"""
def get_timer_frequency() -> int:
"""
Get the frequency, in Hz, of the raw timer.
Returns:
int: Timer frequency in Hz
"""Access platform-specific OpenGL context handles and properties.
def get_wgl_context(window) -> ctypes.c_void_p:
"""
Get the HGLRC of the specified window.
Parameters:
window: Window handle
Returns:
ctypes.c_void_p: WGL context handle (HGLRC)
"""def get_nsgl_context(window) -> ctypes.c_void_p:
"""
Get the NSOpenGLContext of the specified window.
Parameters:
window: Window handle
Returns:
ctypes.c_void_p: NSGL context handle (NSOpenGLContext)
"""def get_glx_context(window) -> ctypes.c_void_p:
"""
Get the GLXContext of the specified window.
Parameters:
window: Window handle
Returns:
ctypes.c_void_p: GLX context handle (GLXContext)
"""
def get_glx_window(window) -> int:
"""
Get the GLXWindow of the specified window.
Parameters:
window: Window handle
Returns:
int: GLX window identifier (GLXWindow)
"""def get_egl_display() -> ctypes.c_void_p:
"""
Get the EGLDisplay used by GLFW.
Returns:
ctypes.c_void_p: EGL display handle (EGLDisplay)
"""
def get_egl_context(window) -> ctypes.c_void_p:
"""
Get the EGLContext of the specified window.
Parameters:
window: Window handle
Returns:
ctypes.c_void_p: EGL context handle (EGLContext)
"""
def get_egl_surface(window) -> ctypes.c_void_p:
"""
Get the EGLSurface of the specified window.
Parameters:
window: Window handle
Returns:
ctypes.c_void_p: EGL surface handle (EGLSurface)
"""def get_os_mesa_context(window) -> ctypes.c_void_p:
"""
Get the OSMesaContext of the specified window.
Parameters:
window: Window handle
Returns:
ctypes.c_void_p: OSMesa context handle (OSMesaContext)
"""
def get_os_mesa_color_buffer(window) -> tuple:
"""
Get the color buffer associated with the specified window.
Parameters:
window: Window handle
Returns:
tuple: (width, height, format, buffer) or None if failed
"""
def get_os_mesa_depth_buffer(window) -> tuple:
"""
Get the depth buffer associated with the specified window.
Parameters:
window: Window handle
Returns:
tuple: (width, height, bytes_per_value, buffer) or None if failed
"""import glfw
# Initialize GLFW
glfw.init()
# Request specific OpenGL version (3.3 Core)
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, glfw.TRUE) # macOS
# Create window with OpenGL context
window = glfw.create_window(800, 600, "OpenGL Context", None, None)
if not window:
glfw.terminate()
raise Exception("Failed to create window")
# Make the context current
glfw.make_context_current(window)
# Enable v-sync
glfw.swap_interval(1)
# Main render loop
while not glfw.window_should_close(window):
glfw.poll_events()
# OpenGL rendering commands go here
# glClear, glDrawArrays, etc.
# Swap front and back buffers
glfw.swap_buffers(window)
glfw.terminate()import glfw
import ctypes
glfw.init()
# Create context first
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
window = glfw.create_window(800, 600, "Function Loading", None, None)
glfw.make_context_current(window)
# Check for extensions
if glfw.extension_supported("GL_ARB_vertex_array_object"):
print("VAO extension supported")
# Load OpenGL functions
gl_clear = glfw.get_proc_address("glClear")
gl_clear_color = glfw.get_proc_address("glClearColor")
if gl_clear and gl_clear_color:
print("Successfully loaded OpenGL functions")
# Convert to callable Python functions
glClear = ctypes.CFUNCTYPE(None, ctypes.c_uint)(gl_clear)
glClearColor = ctypes.CFUNCTYPE(None, ctypes.c_float, ctypes.c_float,
ctypes.c_float, ctypes.c_float)(gl_clear_color)
# Use the functions
glClearColor(0.2, 0.3, 0.3, 1.0)
glClear(0x00004000) # GL_COLOR_BUFFER_BIT
glfw.terminate()import glfw
glfw.init()
# Create main window
main_window = glfw.create_window(800, 600, "Main Window", None, None)
glfw.make_context_current(main_window)
# Load textures, create VAOs, etc. in main context
# ... OpenGL resource creation ...
# Create second window sharing the context
shared_window = glfw.create_window(400, 300, "Shared Context", None, main_window)
# Both windows can now access the same OpenGL resources
while not glfw.window_should_close(main_window) and not glfw.window_should_close(shared_window):
glfw.poll_events()
# Render to main window
glfw.make_context_current(main_window)
# ... render main window ...
glfw.swap_buffers(main_window)
# Render to shared window (can use same resources)
glfw.make_context_current(shared_window)
# ... render shared window ...
glfw.swap_buffers(shared_window)
glfw.terminate()import glfw
def gl_debug_callback(source, type, id, severity, length, message, user_param):
print(f"OpenGL Debug: {message}")
glfw.init()
# Request debug context
glfw.window_hint(glfw.OPENGL_DEBUG_CONTEXT, glfw.TRUE)
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
window = glfw.create_window(800, 600, "Debug Context", None, None)
glfw.make_context_current(window)
# Check if debug context was created
if glfw.get_window_attrib(window, glfw.CONTEXT_DEBUG):
print("Debug context created successfully")
# Set up debug callback (would need OpenGL wrapper like PyOpenGL)
# gl.glDebugMessageCallback(gl_debug_callback, None)
# gl.glEnable(gl.GL_DEBUG_OUTPUT)
glfw.terminate()import glfw
import time
glfw.init()
window = glfw.create_window(800, 600, "Frame Rate", None, None)
glfw.make_context_current(window)
# Disable v-sync for manual frame rate control
glfw.swap_interval(0)
target_fps = 60
frame_time = 1.0 / target_fps
last_time = glfw.get_time()
frame_count = 0
while not glfw.window_should_close(window):
current_time = glfw.get_time()
delta_time = current_time - last_time
glfw.poll_events()
# Render frame
# ... OpenGL rendering ...
glfw.swap_buffers(window)
# Frame rate limiting
frame_time_used = glfw.get_time() - current_time
sleep_time = frame_time - frame_time_used
if sleep_time > 0:
time.sleep(sleep_time)
# FPS counter
frame_count += 1
if current_time - last_time >= 1.0:
fps = frame_count / (current_time - last_time)
glfw.set_window_title(window, f"Frame Rate - FPS: {fps:.1f}")
frame_count = 0
last_time = current_time
glfw.terminate()Install with Tessl CLI
npx tessl i tessl/pypi-glfw