Dynamiczne ładowanie OpenGL przez GLFW w PHP FFI
W podejściu PHP FFI do OpenGL ręczne kopiowanie stałych i typedef z nagłówków GLFW3 prowadzi do nadmiarowego kodu szablonowego. Konwertujemy #define na stałe PHP i wstawiamy funkcje API do sekcji zasobów bez zmian.
Przykład transformacji:
// glfw3.h
#define GLFW_VERSION_MAJOR 3
// glfw3.php
const GLFW_VERSION_MAJOR = 3;
// glfw3.h
GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window);
// glfw3.php (w __halt_compiler())
void glfwMakeContextCurrent(GLFWwindow* window);
Funkcje FFI zachowują się jak metody obiektu proxy i wskaźniki jednocześnie:
$glfwMakeContextCurrent = $glfw->glfwMakeContextCurrent;
$glfwMakeContextCurrent($window);
Proceduralne nakładki dla autouzupełniania
Tworzymy funkcje PHP-opakowania ze statycznym buforowaniem wskaźników dla typowania i wsparcia IDE:
const GLFW_INSTANCE = FFI::cdef(...);
function glfwMakeContextCurrent(mixed ...$args): void {
static $function = GLFW_INSTANCE->glfwMakeContextCurrent;
$function(...$args);
}
To podejście minimalizuje wywołania metod FFI-proxy, zastępując je domknięciami. Wydajność jest zachowana, ponieważ adresy funkcji są statyczne.
Alternatywy (niezalecane):
- Przekazywanie
$glfwjako pierwszego argumentu. global $glfw.
Z stałą GLFW_INSTANCE główny kod upraszcza się:
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);
Dynamiczne ładowanie OpenGL bez opengl32.dll
Funkcje OpenGL są ładowane dynamicznie przez zależne od platformy funkcje GetProcAddress:
- Windows:
wglGetProcAddress - Linux:
glXGetProcAddressARB - Android:
eglGetProcAddress
GLFW ujednolica to w wieloplatformową glfwGetProcAddress:
function glClear(mixed ...$args): void {
static $function = GLFW_INSTANCE->cast(
'PFNGLCLEARPROC',
GLFW_INSTANCE->glfwGetProcAddress('glClear')
);
$function(...$args);
}
Typy takie jak PFNGLCLEARPROC są pobierane z glcorearb.h:
typedef void (*PFNGLCLEARPROC)(GLbitfield mask);
Wsparcie rozszerzeń (NV, AMD → ARB) jest sprawdzane dynamicznie: sprzęt określa dostępne funkcje, sterowniki emulują brakujące.
Generowanie mostów ze źródeł
Automatyzujemy tworzenie glfw3.php (20k+ linii):
- ffi/preprocessor: przekształca nagłówki C w format PHP, wyodrębnia definicje.
- ffi/ide-helper-generator: generuje nakładki z typami argumentów.
Wybrano GLFW 3.3 dla kompatybilności z Ubuntu 24.04. Stałe i funkcje OpenGL są zintegrowane w jeden plik, opengl.php został usunięty.
Zalety:
- Pełna kompatybilność z
ext-glfw. - Wieloplatformowość bez ręcznego dostosowywania.
- Autouzupełnianie i typowanie bez kompilacji.
Co jest ważne
- GLFW_INSTANCE jako globalna stała zapewnia szybki dostęp do FFI bez zmiennych globalnych.
- Typy *PFNGLPROC** z glcorearb.h upraszczają rzutowanie bez ręcznego określania sygnatur.
- glfwGetProcAddress zastępuje platformowy zbiór (WGL/GLX/EGL).
- Generowanie ze źródeł gwarantuje aktualność 20k+ linii.
- Wydajność: statyczna pamięć podręczna minimalizuje narzut metod FFI.
Kod jest gotowy do rysowania trójkątów z buforami i shaderami w następnej części.
— Editorial Team
Brak komentarzy.