Zpět na domů

OpenGL rozšíření v PHP FFI přes GLFW

Článek popisuje implementaci OpenGL rozšíření v PHP FFI přes GLFW bez externích DLL. Automatizována je generace mostů z C hlaviček, procedurální zástupné funkce zajišťují autokompletaci. Plná křížově platformnost s glfwGetProcAddress.

PHP FFI + GLFW: dynamická OpenGL rozšíření
Advertisement 728x90

Dynamické načítání OpenGL přes GLFW v PHP FFI

Při použití FFI přístupu k OpenGL v PHP vede ruční kopírování konstant a typedef z hlavičkových souborů GLFW3 k nadbytečnému opakování kódu. Převádíme #define na PHP konstanty a API funkce vkládáme do sekce s prostředky beze změn.

Příklad transformace:

// glfw3.h
#define GLFW_VERSION_MAJOR 3

// glfw3.php
const GLFW_VERSION_MAJOR = 3;
// glfw3.h
GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window);

// glfw3.php (v __halt_compiler())
void glfwMakeContextCurrent(GLFWwindow* window);

Funkce FFI se chovají jako metody proxy objektu a ukazatele zároveň:

Google AdInline article slot
$glfwMakeContextCurrent = $glfw->glfwMakeContextCurrent;
$glfwMakeContextCurrent($window);

Procedurální zástupné funkce pro automatické doplňování

Vytváříme PHP obalové funkce s static ukládáním ukazatelů pro typizaci a podporu v IDE:

const GLFW_INSTANCE = FFI::cdef(...);

function glfwMakeContextCurrent(mixed ...$args): void {
    static $function = GLFW_INSTANCE->glfwMakeContextCurrent;
    $function(...$args);
}

Tento přístup minimalizuje volání metod FFI proxy a nahrazuje je uzávěry. Výkon zůstává zachován, protože adresy funkcí jsou statické.

Alternativy (nedoporučují se):

Google AdInline article slot
  • Předávání $glfw jako prvního argumentu.
  • global $glfw.

S konstantou GLFW_INSTANCE se hlavní kód zjednodušuje:

require 'src/glfw3.php';

if (!glfwInit()) exit(-1);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
$window = glfwCreateWindow(640, 480, 'Hello World', null, null);

Dynamické načítání OpenGL bez opengl32.dll

Funkce OpenGL se načítají dynamicky přes platformově závislé funkce GetProcAddress:

  • Windows: wglGetProcAddress
  • Linux: glXGetProcAddressARB
  • Android: eglGetProcAddress

GLFW to sjednocuje do multiplatformní glfwGetProcAddress:

Google AdInline article slot
function glClear(mixed ...$args): void {
    static $function = GLFW_INSTANCE->cast(
        'PFNGLCLEARPROC',
        GLFW_INSTANCE->glfwGetProcAddress('glClear')
    );
    $function(...$args);
}

Typy jako PFNGLCLEARPROC se berou z glcorearb.h:

typedef void (*PFNGLCLEARPROC)(GLbitfield mask);

Podpora rozšíření (NV, AMD → ARB) se kontroluje dynamicky: hardware určuje dostupné funkce, ovladače emulují chybějící.

Generování mostů ze zdrojových kódů

Automatizujeme vytváření glfw3.php (20k+ řádků):

  • ffi/preprocessor: převádí C hlavičkové soubory do PHP formátu, extrahuje definice.
  • ffi/ide-helper-generator: generuje zástupné funkce s typy argumentů.

Zvolena GLFW 3.3 pro kompatibilitu s Ubuntu 24.04. Konstanty a funkce OpenGL jsou integrovány do jednoho souboru, opengl.php je odstraněn.

Výhody:

  • Úplná kompatibilita s ext-glfw.
  • Multiplatformnost bez ručního přizpůsobování.
  • Automatické doplňování a typizace bez kompilace.

Co je důležité

  • GLFW_INSTANCE jako globální konstanta zajišťuje rychlý přístup k FFI bez globálních proměnných.
  • *PFNGLPROC** typy z glcorearb.h zjednodušují přetypování bez ručního zadávání signatur.
  • glfwGetProcAddress nahrazuje platformní zoo (WGL/GLX/EGL).
  • Generování ze zdrojových kódů zaručuje aktuálnost 20k+ řádků.
  • Výkon: static cache minimalizuje režii metod FFI.

Kód je připraven k vykreslování trojúhelníků s buffery a shadery v další části.

— Editorial Team

Advertisement 728x90

Číst dál