Skip to content
Search

Simple DirectMedia Layer

lastmod 2026-03-27created 2014-03-1757 edits

List of SDL API

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

Basics

Video

Input Events

Force Feedback

  • Initialization and Shutdown
    • SDL_Init
    • SDL_InitSubSystem
    • SDL_Quit
    • SDL_QuitSubSystem
  • Configuration Variables
    • SDL_GetHint
    • SDL_SetHint
    • SDL_SetHintWithPriority
  • Error Handling
    • SDL_ClearError
    • SDL_GetError
    • SDL_SetError
  • Log Handling
    • SDL_Log
    • SDL_LogCritical
    • SDL_LogDebug
    • SDL_LogError
    • SDL_LogInfo
    • SDL_LogMessage
    • SDL_LogVerbose
    • SDL_LogWarn
  • Assertions
    • SDL_assert
  • Querying SDL Version
    • SDL_GetVersion
  • Display and Window Management
    • SDL_CreateWindow
    • SDL_DestroyWindow
    • SDL_GetWindowPixelFormat
    • SDL_GetWindowPosition
    • SDL_GetWindowSize
  • 2D Accelerated Rendering
    • SDL_CreateRenderer
    • SDL_CreateSoftwareRenderer
    • SDL_CreateTexture
    • SDL_LockTexture
    • SDL_RenderClear
    • SDL_RenderCopy
    • SDL_RenderCopyEx
    • SDL_RenderDrawLine
    • SDL_RenderDrawLines
    • SDL_RenderDrawPoint
    • SDL_RenderDrawPoints
    • SDL_RenderDrawRect
    • SDL_RenderDrawRects
    • SDL_RenderFillRect
    • SDL_RenderFillRects
    • SDL_SetRenderDrawBlendMode
    • SDL_SetRenderDrawColor
    • SDL_SetRenderTarget
    • SDL_SetTextureAlphaMod
    • SDL_SetTextureBlendMode
    • SDL_SetTextureColorMod
    • SDL_UnlockTexture
    • SDL_UpdateTexture
    • SDL_UpdateYUVTexture
  • Pixel Formats and Conversion Routines
  • Rectangle Functions
  • Surface Creation and Simple Drawing
  • Platform-specific Window Management
  • Clipboard Handling
  • Force Feedback Support

Audio

Threads

Timers

File Abstraction

  • Audio Device Management,
    Playing and Recording
  • Thread Management
  • Thread Synchronization Primitives
  • Atomic Operations
  • Thread Issue
  • Timer Support
  • Filesystem Paths
  • File I/O Abstraction

Shared Object Support

Platform and CPU Information

Power Management

Additional

  • Shared Object Loading
    and Function Lookup
  • Platform Detection
  • CPU Feature Detection
  • Byte Order and Byte Swapping
  • Bit Manipulation
  • Power Management Status
  • Platform-specific functionality
  • Other

SDL_image

SDL_ttf

SDL_mixer

OpenGL

Structure

Libraries

SDL3

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

SDL_VIDEODRIVER=wayland

When X11 apps break

SDL_VIDEODRIVER=x11

Needed in Wayland-only environments

DISPLAY=:0

X11 display not set

LIBGL_ALWAYS_SOFTWARE=1

GPU driver problems

SDL_VIDEO_X11_FORCE_EGL=1

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

DISPLAY=:0, SDL_VIDEODRIVER=x11

Wayland session

SDL_VIDEODRIVER=x11, SDL_VIDEO_X11_FORCE_EGL=1

SSH remote

DISPLAY=:0, SDL_VIDEODRIVER=x11

VM (VirtualBox, etc.)

SDL_VIDEODRIVER=x11

No GPU driver

LIBGL_ALWAYS_SOFTWARE=1

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.

$ g++ -std=c++11 main.cpp -lmingw32 -lSDL2main -lSDL2 -lopengl32

implicit entry/start for main executable

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.

#ifdef main
#undef main
#endif

Renderer already associated with window

You can see an error message like the following via SDL_GetError().

Renderer already associated with window

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

./configure
make
make install

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 Wiki

Tutorial

Guide

Guide: Initialize

References


  1. Lazyfoo.net.140828.backup.7z ↩

  2. Inside_linux-happy_hacking-maso200109-use_sdl_library_02.pdf ↩

  3. CODEpendent-wx-sdl_tutorial_part_1.pdf ↩

  4. Demonstration_of_SDL2+FFmpeg_player_based_on.pdf ↩

author Zer0 sitemap