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ň:
$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):
- Předávání
$glfwjako 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:
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
Zatím žádné komentáře.