Simple DirectMedia Layer
lastmod 2026-03-27created 2014-03-1757 edits
|
Simple DirectMedia Layer (SDL) is a cross-platform multimedia library written in the C programming language. It abstracts layers such as video, audio, and user input so that programs can run on multiple operating systems, including Linux, Microsoft Windows, and Mac OS X. The library manages video, events, digital audio, CD-ROM, sound, threads, shared object loading, networking, and timers.
SDL 2.0 API by Category
|
|
|
|
|
|
|
|
|
|
|
|
Structure
Libraries
SDL3
- SDL3/FrontPage - SDL Wiki
- libsdl-org/SDL: Simple Directmedia Layer
- Simple DirectMedia Layer - Language Bindings
- Lazy Foo' Productions - Beginning Game Programming v3.0
Local Download
- SDL2 2.0.4
-
SDL2-2.0.4.tar.gz
Automatic detection and setup of SDL environment variables
When running pygame + opengl on linux, there is an issue where SDL-related environment variables must be set for it to run properly.
A way is needed to find and set these environment variables automatically so it just runs.
| WARNING |
| This answer was auto-generated by Claude-Code |
Common problem patterns
| Environment variable | Situation |
| | When X11 apps break |
| | Needed in Wayland-only environments |
| | X11 display not set |
| | GPU driver problems |
| | When EGL must be forced |
Auto-detection Python module
import os
import subprocess
import sys
from pathlib import Path
def detect_display_server() -> str:
"""
Detect current display server (Wayland or X11)
현재 디스플레이 서버 감지
"""
# Wayland 세션 확인
if os.environ.get("WAYLAND_DISPLAY"):
return "wayland"
if os.environ.get("XDG_SESSION_TYPE", "").lower() == "wayland":
return "wayland"
# X11 세션 확인
if os.environ.get("DISPLAY"):
return "x11"
return "unknown"
def find_x11_display() -> str | None:
"""
Find available X11 DISPLAY value
사용 가능한 X11 DISPLAY 값 찾기
"""
# 이미 설정된 경우
if os.environ.get("DISPLAY"):
return os.environ["DISPLAY"]
# /tmp/.X11-unix 소켓 탐색
x11_dir = Path("/tmp/.X11-unix")
if x11_dir.exists():
sockets = sorted(x11_dir.glob("X*"))
if sockets:
# X0 -> :0, X1 -> :1 ...
display_num = sockets[0].name[1:] # 'X' 제거
return f":{display_num}"
return None
def check_opengl_support() -> dict:
"""
Check OpenGL driver availability via glxinfo
glxinfo로 OpenGL 드라이버 가용성 확인
"""
result = {"has_glx": False, "has_egl": False, "renderer": "unknown"}
try:
out = subprocess.check_output(
["glxinfo", "-B"],
stderr=subprocess.DEVNULL,
timeout=3,
).decode()
result["has_glx"] = True
for line in out.splitlines():
if "OpenGL renderer" in line:
result["renderer"] = line.split(":", 1)[-1].strip()
except (FileNotFoundError, subprocess.CalledProcessError, subprocess.TimeoutExpired):
pass
# EGL 확인
try:
out = subprocess.check_output(
["eglinfo"],
stderr=subprocess.DEVNULL,
timeout=3,
).decode()
result["has_egl"] = "EGL_VERSION" in out
except (FileNotFoundError, subprocess.CalledProcessError, subprocess.TimeoutExpired):
pass
return result
def is_ssh_session() -> bool:
"""
Detect if running inside SSH session
SSH 세션 여부 감지
"""
return bool(os.environ.get("SSH_CLIENT") or os.environ.get("SSH_TTY"))
def is_virtual_machine() -> bool:
"""
Detect if running inside a virtual machine (VirtualBox, VMware, etc.)
가상머신 여부 감지
"""
try:
out = subprocess.check_output(
["systemd-detect-virt", "--vm"],
stderr=subprocess.DEVNULL,
timeout=2,
).decode().strip()
return out not in ("none", "")
except Exception:
pass
# /sys/class/dmi로 폴백
try:
dmi = Path("/sys/class/dmi/id/product_name").read_text().lower()
return any(v in dmi for v in ("virtualbox", "vmware", "kvm", "qemu"))
except Exception:
return False
def resolve_sdl_env() -> dict[str, str]:
"""
Automatically resolve required SDL environment variables
필요한 SDL 환경변수 자동 결정
Returns:
dict: 설정해야 할 환경변수 딕셔너리
"""
env_patch: dict[str, str] = {}
display_server = detect_display_server()
opengl_info = check_opengl_support()
ssh = is_ssh_session()
vm = is_virtual_machine()
print(f"[sdl_env] Display server : {display_server}")
print(f"[sdl_env] SSH session : {ssh}")
print(f"[sdl_env] Virtual machine: {vm}")
print(f"[sdl_env] OpenGL renderer: {opengl_info['renderer']}")
# ── DISPLAY 설정 (X11) ──────────────────────────────────────
if not os.environ.get("DISPLAY"):
found = find_x11_display()
if found:
env_patch["DISPLAY"] = found
print(f"[sdl_env] DISPLAY 자동 설정: {found}")
# ── SDL_VIDEODRIVER ──────────────────────────────────────────
if not os.environ.get("SDL_VIDEODRIVER"):
if ssh or vm:
# SSH/VM 환경: offscreen 또는 x11 강제
env_patch["SDL_VIDEODRIVER"] = "x11"
elif display_server == "wayland":
# Wayland + OpenGL 조합은 x11로 강제하는 게 안정적
env_patch["SDL_VIDEODRIVER"] = "x11"
elif display_server == "x11":
env_patch["SDL_VIDEODRIVER"] = "x11"
# ── EGL 강제 (Wayland 환경 또는 Mesa 환경) ──────────────────
if display_server == "wayland" or "mesa" in opengl_info["renderer"].lower():
if not os.environ.get("SDL_VIDEO_X11_FORCE_EGL"):
env_patch["SDL_VIDEO_X11_FORCE_EGL"] = "1"
# ── 소프트웨어 렌더링 폴백 ───────────────────────────────────
# GPU 드라이버 없고 EGL도 없는 경우
if not opengl_info["has_glx"] and not opengl_info["has_egl"]:
print("[sdl_env] ⚠️ HW OpenGL 불가 → 소프트웨어 렌더링 폴백")
env_patch["LIBGL_ALWAYS_SOFTWARE"] = "1"
env_patch["SDL_RENDER_DRIVER"] = "software"
return env_patch
def apply_sdl_env(verbose: bool = True) -> dict[str, str]:
"""
Apply resolved SDL env vars to the current process environment
해결된 SDL 환경변수를 현재 프로세스에 적용
Must be called BEFORE importing pygame
pygame import 전에 반드시 호출해야 함
"""
patch = resolve_sdl_env()
for key, val in patch.items():
os.environ[key] = val
if verbose:
print(f"[sdl_env] SET {key}={val}")
return patch
Usage:
# ── main.py ──────────────────────────────────────────────────────
# IMPORTANT: apply_sdl_env() must be called before importing pygame
# 중요: pygame import 전에 반드시 apply_sdl_env() 호출
from sdl_env import apply_sdl_env
apply_sdl_env() # ← 여기서 먼저 설정
import pygame
from pygame.locals import *
from OpenGL.GL import *
def main():
pygame.init()
screen = pygame.display.set_mode(
(1280, 720),
DOUBLEBUF | OPENGL,
)
pygame.display.set_caption("pygame + OpenGL")
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
glClearColor(0.1, 0.1, 0.15, 1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
pygame.display.flip()
pygame.quit()
if __name__ == "__main__":
main()
Behavior by environment:
| Environment | Auto-set |
| Regular X11 | |
| Wayland session | |
| SSH remote | |
| VM (VirtualBox, etc.) | |
| No GPU driver | |
When used with imgui_bundle:
from sdl_env import apply_sdl_env
apply_sdl_env() # hello_imgui.run() 전에 호출
from imgui_bundle import hello_imgui, imgui
# ...
hello_imgui.run(runner_params)
Troubleshooting
main() LINKER ERROR
An error message like the following may be printed.
xxx error LNK2019: _WinMain@16 외부 기호(_WinMainCRTStartup 함수에서 참조)를 확인하지 못했습니다.
xxx fatal error LNK1120: 1개의 확인할 수 없는 외부 참조입니다.
This error occurs because SDL defines main as WinMain. Link SDL.lib and SDLmain.lib.
When using MinGW, do the following.
implicit entry/start for main executable
- Stackoverflow: Why SDL defines main macro?
- Stackoverflow: SDL Error Undefined symbols for architecture x86_64 "_SDL_main"
When using SDL with clang, an error message like the following may be printed.
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable.
maybe you meant: _SDL_main
ld: symbol(s) not found for architecture x86_64
In this case, it happens because main is defined as a macro. Undefine the macro as follows.
Renderer already associated with window
You can see an error message like the following via SDL_GetError().
In this case, it means a Renderer has already been created for that Window. Look for the Renderer that was already created.
MSYS DirectX Symbol error
When installing as above in MSYS, DirectX-related symbols (__in, etc.) may not be found. In this case, install DirectX properly.
OpenGL.error.Error: Attempt to retrieve context when no valid context
When running under Wayland on Ubuntu 20.04 or later, the following error may be printed:
pygame-ce 2.4.1 (SDL 2.28.5, Python 3.11.4)
/home/yourname/Project/ddrm/test.py:13: Warning: PyGame seems to be running through X11 on top of wayland, instead of wayland directly
...
OpenGL.error.Error: Attempt to retrieve context when no valid context
Simply set the SDL_VIDEO_X11_FORCE_EGL=1 environment variable.
See also
Favorite site
- SDL website
- Wikipedia (en) description of SDL
- libsdl-android (SDL library for Android, including several games)
SDL Wiki
Tutorial
- Lazy Foo' Productions (SDL Tutorial) 1
- SDL2: 01. Window and renderer (1)
- [Recommended] SDL Tutorial: Lesson 1 - Installing and setting up SDL and showing an image on screen
- Exploring SDL
- Transfer of SDL Game Framework Series. A part 1 — SDL Tutorial Basics
Guide
- AESOP Example of using SDL on Android
- Using OpenGL With SDL
- SDL basics
- Empirical approach to CMAKE
- Using gtest with CMake
- Using the SDL library for game development (2) 2
- SDL Tutorial Lesson 7: Fonts
- SDL coding #2 Printing Korean text
Link Third-party library
- wx-sdl: A tutorial on combining wxWidgets with SDL 3
- Demonstration of SDL2.0+FFmpeg player based on 4
- Overview of SDL GUI toolkits