throw all gl functions in global namespace, that'll show them

main
eater 2 years ago
parent 1f3881bdc4
commit 112b26a4b5
Signed by: eater
GPG Key ID: AD2560A0F84F0759

@ -4,6 +4,58 @@ if ( ! file_exists(__DIR__ . "/../resources/gl.xml")) {
copy("https://cvs.khronos.org/svn/repos/ogl/trunk/doc/registry/public/api/gl.xml", __DIR__ . "/../resources/gl.xml");
}
$types = [
"int" => [
"char",
"unsigned char",
"int",
"unsigned int",
"short",
"unsigned short",
"long",
"unsigned long",
"long long",
"unsigned long long",
"GLsizeiptr",
"GLintptr",
"GLenum",
"GLboolean",
"GLbitfield",
"GLvoid",
"GLbyte",
"GLshort",
"GLint",
"GLubyte",
"GLushort",
"GLuint",
"GLsizei",
"GLchar",
"GLsizeiptr",
"GLintptr",
"GLsync",
"GLeglImageOES",
"GLeglClientBufferEXT",
"GLuint64",
"GLint64",
"GLuint64EXT",
"GLint64EXT",
"GLfixed",
"GLhalfNV",
"GLhandleARB",
"GLcharARB",
"GLintptrARB",
"GLsizeiptrARB",
"GLclampx",
],
"float" => [
'GLfloat',
'GLdouble',
'float',
'double',
],
];
$xml = new DOMDocument();
$xml->loadXML(file_get_contents(__DIR__ . "/../resources/gl.xml"));
@ -13,6 +65,8 @@ $data = file_get_contents(__DIR__ . "/../headers/gl.h");
$data .= "// GENERATED DATA START\n\n";
$php = "<?php\n\nuse Cijber\GraphicsToolkit\GL;\nuse FFI\Cdata;\n\n// generated gl functions\n\n";
/** @var DOMNode $node */
foreach ($commands->childNodes as $node) {
if ($node->nodeName !== "command") {
@ -26,15 +80,47 @@ foreach ($commands->childNodes as $node) {
$name = $proto->getElementsByTagName("name")[0];
$name->remove();
$returnType = trim($proto->textContent);
$returnType = trim($proto->textContent);
$functionName = trim($name->textContent);
$args = [];
$args = [];
$names = [];
$phpArgs = [];
foreach ($node->getElementsByTagName("param") as $param) {
$args[] = trim($param->textContent);
$name = $param->getElementsByTagName('name')->item(0);
$name->remove();
$type = trim($param->textContent);;
if (($type === 'void *' || $type === 'const void *') && $functionName === 'glVertexAttribPointer' || $functionName === 'glDrawElements') {
$type = 'unsigned long long';
}
$phpType = "";
foreach ($types as $foundPhpType => $cTypes) {
if (false !== array_search($type, $cTypes)) {
$phpType = $foundPhpType;
break;
}
}
if ($phpType !== "") {
$phpArgs[] = $phpType . ' $' . $name->textContent;
} else {
$phpArgs[] = '$' . $name->textContent;
}
$names[] = '$' . $name->textContent;
$args[] = $type;
}
$data .= "typedef $returnType (* FUNC_$functionName) (" . implode(", ", $args) . ");\n";
$functionBody = "(" . implode(", ", $phpArgs) . ") {\n static \$proc;\n return (\$proc ??= GL::getProcAddress('" . strtolower($functionName[2]) . substr($functionName, 3) . "'))(" . implode(", ", $names) . ");\n}\n\n";;
$php .= "function $functionName$functionBody";
}
file_put_contents(__DIR__ . "/../headers/gl_generated.h", $data);
file_put_contents(__DIR__ . "/../headers/gl_generated.h", $data);
file_put_contents(__DIR__ . "/../src/gl_functions.php", $php);

@ -6,7 +6,14 @@ use Cijber\GraphicsToolkit\GLFW;
use Cijber\GraphicsToolkit\Utils;
set_error_handler(function($severity, $message, $file, $line) {
global $error;
$error = new RuntimeException("$severity: $message [$file($line)]");
Fiber::suspend();
});
include(__DIR__ . "/../vendor/autoload.php");
function main() {
GL::init();
@ -31,63 +38,66 @@ function main() {
$window,
function($window, $width, $height) use (&$viewportHeight, &$viewportWidth) {
echo "Size: $width x $height\n";
GL::viewport(0, 0, $viewportWidth = $width, $viewportHeight = $height);
glViewport(0, 0, $viewportWidth = $width, $viewportHeight = $height);
}
);
GL::viewport(0, 0, 800, 600);
glViewport(0, 0, 800, 600);
GL::debugMessageCallback(function($source, $type, $id, $severity, $length, $message, $user) {
glDebugMessageCallback(function($source, $type, $id, $severity, $length, $message, $user) {
$message = substr($message, 0, $length);
var_dump(["source" => $source, "type" => $type, "id" => $id, "severity" => $severity, "message" => $message, "gl" => GL::$lastCall]);
var_dump(["source" => $source, "type" => $type, "id" => $id, "severity" => $severity, "message" => $message, "call" => debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)[2]]);
}, null);
// GL::debugMessageCallback($callback, null);
// glDebugMessageCallback($callback, null);
GL::enable(GL::DEBUG_OUTPUT);
GL::enable(GL::DEBUG_OUTPUT_SYNCHRONOUS);
GL::enable(GL::BLEND);
GL::blendFunc(GL::SRC_ALPHA, GL::ONE_MINUS_SRC_ALPHA);
glEnable(GL::DEBUG_OUTPUT);
glEnable(GL::DEBUG_OUTPUT_SYNCHRONOUS);
$vertexShader = GL::createShader(GL::VERTEX_SHADER);
$vertexShaderSource = file_get_contents(__DIR__ . "/../shaders/vertex.glsl");
glEnable(GL::BLEND);
// glEnable(GL::BLEND);
glBlendFunc(GL::SRC_ALPHA, GL::ONE_MINUS_SRC_ALPHA);
GL::shaderSource($vertexShader, 1, $vertexShaderSource, null);
$vertexShader = \glCreateShader(GL::VERTEX_SHADER);
$vertexShaderSource = file_get_contents(__DIR__ . "/../shaders/vertex.glsl");
GL::shaderSource($vertexShader, [$vertexShaderSource]);
GL::compileShader($vertexShader);
GL::getShaderiv($vertexShader, GL::COMPILE_STATUS, $success);
glCompileShader($vertexShader);
glGetShaderiv($vertexShader, GL::COMPILE_STATUS, Utils::pointer($success, "int32_t"));
if ( ! $success) {
GL::getShaderiv($vertexShader, GL::INFO_LOG_LENGTH, $logLength);
GL::getShaderInfoLog($vertexShader, $infoLog, $logLength);
if ( ! $success->cdata) {
glGetShaderiv($vertexShader, GL::INFO_LOG_LENGTH, Utils::pointer($logLength, "int32_t"));
glGetShaderInfoLog($vertexShader, $logLength, Utils::null(), Utils::stringBuffer($infoLog, $logLength->cdata));
die("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n\t$infoLog");
}
$fragmentShader = GL::createShader(GL::FRAGMENT_SHADER);
$fragmentShader = glCreateShader(GL::FRAGMENT_SHADER);
$fragmentShaderSource = file_get_contents(
__DIR__ . "/../shaders/fragment.glsl"
);
GL::shaderSource($fragmentShader, 1, $fragmentShaderSource, null);
GL::compileShader($fragmentShader);
GL::getShaderiv($fragmentShader, GL::COMPILE_STATUS, $success);
GL::shaderSource($fragmentShader, [$fragmentShaderSource]);
glCompileShader($fragmentShader);
glGetShaderiv($fragmentShader, GL::COMPILE_STATUS, FFI::addr($success));
if ( ! $success) {
GL::getShaderiv($fragmentShader, GL::INFO_LOG_LENGTH, $logLength);
GL::GetShaderInfoLog($fragmentShader, $infoLog, $logLength);
die("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n\t$infoLog");
if ( ! $success->cdata) {
glGetShaderiv($fragmentShader, GL::INFO_LOG_LENGTH, Utils::pointer($logLength, "int32_t"));
glGetShaderInfoLog($fragmentShader, $logLength->cdata, Utils::pointer($result, 'int32_t'), Utils::stringBuffer($infoLog, $logLength->cdata));
$infoLog = FFI::string($infoLog, $result->cdata);
die("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n\t{$infoLog}");
}
$shaderProgram = GL::createProgram();
GL::attachShader($shaderProgram, $vertexShader);
GL::attachShader($shaderProgram, $fragmentShader);
GL::linkProgram($shaderProgram);
$shaderProgram = glCreateProgram();
glAttachShader($shaderProgram, $vertexShader);
glAttachShader($shaderProgram, $fragmentShader);
glLinkProgram($shaderProgram);
GL::deleteShader($vertexShader);
GL::deleteShader($fragmentShader);
glDeleteShader($vertexShader);
glDeleteShader($fragmentShader);
$vertices = [
-0.5,
@ -102,20 +112,21 @@ function main() {
];
$float = Utils::arrayOf('float', $vertices);
GL::genVertexArrays(1, $VAO);
GL::genBuffers(1, $VBO);
GL::bindVertexArray($VAO);
GL::bindBuffer(GL::ARRAY_BUFFER, $VBO);
GL::bufferData(
glGenVertexArrays(1, Utils::pointer($VAO, 'uint32_t'));
glGenBuffers(1, Utils::pointer($VBO, 'uint32_t'));
$VAO = $VAO->cdata;
$VBO = $VBO->cdata;
glBindVertexArray($VAO);
glBindBuffer(GL::ARRAY_BUFFER, $VBO);
glBufferData(
GL::ARRAY_BUFFER,
FFI::sizeof($float),
$float,
GL::STATIC_DRAW
);
GL::vertexAttribPointer(
glVertexAttribPointer(
0,
3,
GL::FLOAT,
@ -124,10 +135,10 @@ function main() {
0
);
GL::enableVertexAttribArray(0);
glEnableVertexAttribArray(0);
GL::bindBuffer(GL::ARRAY_BUFFER, 0);
GL::bindVertexArray(0);
glBindBuffer(GL::ARRAY_BUFFER, 0);
glBindVertexArray(0);
$textureRow = Cairo::format_stride_for_width(Cairo::FORMAT_RGB24, 400);
$textureData = FFI::new(FFI::arrayType(FFI::type("unsigned char"), [$textureRow * 400]));
@ -142,65 +153,57 @@ function main() {
Cairo::fill($cairo);
Cairo::surface_flush($surface);
Gl::genTextures(1, $texture);
GL::bindTexture(GL::TEXTURE_2D, $texture);
glGenTextures(1, Utils::pointer($texture, "uint32_t"));
$texture = $texture->cdata;
glBindTexture(GL::TEXTURE_2D, $texture);
gl::texParameteri(GL::TEXTURE_2D, GL::TEXTURE_WRAP_S, GL::REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method)
gl::texParameteri(GL::TEXTURE_2D, GL::TEXTURE_WRAP_T, GL::REPEAT);
glTexParameteri(GL::TEXTURE_2D, GL::TEXTURE_WRAP_S, GL::REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method)
glTexParameteri(GL::TEXTURE_2D, GL::TEXTURE_WRAP_T, GL::REPEAT);
// set texture filtering parameters
gl::texParameteri(GL::TEXTURE_2D, GL::TEXTURE_MIN_FILTER, GL::LINEAR);
gl::texParameteri(GL::TEXTURE_2D, GL::TEXTURE_MAG_FILTER, GL::LINEAR);
glTexParameteri(GL::TEXTURE_2D, GL::TEXTURE_MIN_FILTER, GL::LINEAR);
glTexParameteri(GL::TEXTURE_2D, GL::TEXTURE_MAG_FILTER, GL::LINEAR);
GL::texImage2D(GL::TEXTURE_2D, 0, GL::RGBA, 400, 400, 0, GL::BGRA, GL::UNSIGNED_BYTE, $textureData);
glTexImage2D(GL::TEXTURE_2D, 0, GL::RGBA, 400, 400, 0, GL::BGRA, GL::UNSIGNED_BYTE, $textureData);
$vertexShader = GL::createShader(GL::VERTEX_SHADER);
$vertexShader = glCreateShader(GL::VERTEX_SHADER);
$vertexShaderSource = file_get_contents(__DIR__ . "/../shaders/sq_vertex_shader.glsl");
GL::shaderSource(
$vertexShader,
1,
$vertexShaderSource,
null
);
GL::shaderSource($vertexShader, [$vertexShaderSource]);
glCompileShader($vertexShader);
glGetShaderiv($vertexShader, GL::COMPILE_STATUS, Utils::pointer($success, 'int32_t'));
GL::compileShader($vertexShader);
GL::getShaderiv($vertexShader, GL::COMPILE_STATUS, $success);
if ( ! $success) {
GL::getShaderiv($vertexShader, GL::INFO_LOG_LENGTH, $logLength);
GL::getShaderInfoLog($vertexShader, $infoLog, $logLength);
if ( ! $success->cdata) {
glGetShaderiv($vertexShader, GL::INFO_LOG_LENGTH, Utils::pointer($logLength, "int32_t"));
glGetShaderInfoLog($vertexShader, $logLength, Utils::null(), Utils::stringBuffer($infoLog, $logLength->cdata));
die("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n\t$infoLog");
}
$fragmentShader = GL::createShader(GL::FRAGMENT_SHADER);
$fragmentShader = glCreateShader(GL::FRAGMENT_SHADER);
$fragmentShaderSource = file_get_contents(
__DIR__ . "/../shaders/sq_fragment_shader.glsl"
);
GL::shaderSource(
$fragmentShader,
1,
$fragmentShaderSource,
null
);
GL::compileShader($fragmentShader);
GL::getShaderiv($fragmentShader, GL::COMPILE_STATUS, $success);
GL::shaderSource($fragmentShader, [$fragmentShaderSource]);
glCompileShader($fragmentShader);
glGetShaderiv($fragmentShader, GL::COMPILE_STATUS, FFI::addr($success));
if ( ! $success) {
GL::getShaderiv($fragmentShader, GL::INFO_LOG_LENGTH, $logLength);
GL::GetShaderInfoLog($fragmentShader, $infoLog, $logLength);
die("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n\t$infoLog");
if ( ! $success->cdata) {
glGetShaderiv($fragmentShader, GL::INFO_LOG_LENGTH, Utils::pointer($logLength, "int32_t"));
glGetShaderInfoLog($fragmentShader, $logLength->cdata, Utils::pointer($result, 'int32_t'), Utils::stringBuffer($infoLog, $logLength->cdata));
$infoLog = FFI::string($infoLog, $result->cdata);
die("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n\t{$infoLog}");
}
$squareProgram = GL::createProgram();
GL::attachShader($squareProgram, $vertexShader);
GL::attachShader($squareProgram, $fragmentShader);
GL::linkProgram($squareProgram);
$squareProgram = glCreateProgram();
glAttachShader($squareProgram, $vertexShader);
glAttachShader($squareProgram, $fragmentShader);
glLinkProgram($squareProgram);
GL::deleteShader($vertexShader);
GL::deleteShader($fragmentShader);
glDeleteShader($vertexShader);
glDeleteShader($fragmentShader);
$sq = [
@ -240,15 +243,18 @@ function main() {
];
$float = Utils::arrayOf('float', $sq);
GL::genVertexArrays(1, $SQUARE_VAO);
GL::genBuffers(1, $VBO);
GL::genBuffers(1, $EBO);
glGenVertexArrays(1, Utils::pointer($SQUARE_VAO, 'uint32_t'));
$SQUARE_VAO = $SQUARE_VAO->cdata;
glGenBuffers(1, Utils::pointer($VBO, 'uint32_t'));
$VBO = $VBO->cdata;
glGenBuffers(1, Utils::pointer($EBO, 'uint32_t'));
$EBO = $EBO->cdata;
GL::bindVertexArray($SQUARE_VAO);
glBindVertexArray($SQUARE_VAO);
GL::bindBuffer(GL::ARRAY_BUFFER, $VBO);
GL::bufferData(
glBindBuffer(GL::ARRAY_BUFFER, $VBO);
glBufferData(
GL::ARRAY_BUFFER,
FFI::sizeof($float),
$float,
@ -256,46 +262,48 @@ function main() {
);
$indices = Utils::arrayOf("unsigned int", [0, 1, 3, 1, 2, 3]);
GL::bindBuffer(GL::ELEMENT_ARRAY_BUFFER, $EBO);
GL::bufferData(
glBindBuffer(GL::ELEMENT_ARRAY_BUFFER, $EBO);
glBufferData(
GL::ELEMENT_ARRAY_BUFFER,
FFI::sizeof($indices),
$indices,
GL::STATIC_DRAW,
);
GL::vertexAttribPointer(0, 3, GL::FLOAT, false, 8 * 4, 0);
GL::enableVertexAttribArray(0);
GL::vertexAttribPointer(1, 3, GL::FLOAT, false, 8 * 4, 3 * 4);
GL::enableVertexAttribArray(1);
GL::vertexAttribPointer(2, 2, GL::FLOAT, false, 8 * 4, 6 * 4);
GL::enableVertexAttribArray(2);
glVertexAttribPointer(0, 3, GL::FLOAT, 0, 8 * 4, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL::FLOAT, 0, 8 * 4, 3 * 4);
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL::FLOAT, 0, 8 * 4, 6 * 4);
glEnableVertexAttribArray(2);
GL::useProgram($squareProgram);
$location = GL::getUniformLocation($squareProgram, "ourTexture");
GL::uniform1i($location, 0);
$viewportSizeLocation = GL::getUniformLocation($squareProgram, "viewportSize");
glUseProgram($squareProgram);
$location = glGetUniformLocation($squareProgram, "ourTexture");
glUniform1i($location, 0);
$viewportSizeLocation = glGetUniformLocation($squareProgram, "viewportSize");
while ( ! GLFW::windowShouldClose($window)) {
processInput($window);
GL::clearColor(0.2, 0.3, 0.3, 1.0);
GL::clear(GL::COLOR_BUFFER_BIT);
glClearColor(0.2, 0.3, 0.3, 1.0);
glClear(GL::COLOR_BUFFER_BIT);
glUseProgram($squareProgram);
GL::useProgram($shaderProgram);
GL::bindVertexArray($VAO);
GL::drawArrays(GL::TRIANGLES, 0, 3);
glActiveTexture(GL::TEXTURE0);
glBindTexture(GL::TEXTURE_2D, $texture);
GL::activeTexture(GL::TEXTURE0);
GL::bindTexture(GL::TEXTURE_2D, $texture);
glBindVertexArray($VAO);
glDrawArrays(GL::TRIANGLES, 0, 3);
GL::useProgram($squareProgram);
GL::uniform2i($viewportSizeLocation, $viewportWidth, $viewportHeight);
GL::bindVertexArray($SQUARE_VAO);
glActiveTexture(GL::TEXTURE0);
glBindTexture(GL::TEXTURE_2D, $texture);
$f = FFI::new("long long");
$f->cdata = 0;
GL::drawElements(GL::TRIANGLES, 6, GL::UNSIGNED_INT, FFI::cast('void *', $f));
glUseProgram($squareProgram);
glUniform2i($viewportSizeLocation, $viewportWidth, $viewportHeight);
glBindVertexArray($SQUARE_VAO);
glDrawElements(GL::TRIANGLES, 6, GL::UNSIGNED_INT, 0);
GLFW::pollEvents();
GLFW::swapBuffers($window);
@ -310,4 +318,11 @@ function processInput($window) {
}
}
main();
global $error;
$error = null;
$fiber = new Fiber(fn() => main());
$fiber->start();
if ($error !== null) {
throw $error;
}

File diff suppressed because it is too large Load Diff

@ -10,7 +10,7 @@ uniform ivec2 viewportSize;
void main()
{
ivec2 txtSize = textureSize(ourTexture, 0);
vec2 coord = vec2(gl_FragCoord.x / txtSize.x, -gl_FragCoord.y / txtSize.y);
vec2 coord = vec2(gl_FragCoord.x / txtSize.x, (viewportSize.y - gl_FragCoord.y) / txtSize.y);
float rest = coord.y - floor(coord.y);
FragColor = texture(ourTexture, coord);

@ -6,33 +6,9 @@ namespace Cijber\GraphicsToolkit;
use Cijber\GraphicsToolkit\Consts\GLConsts;
use FFI;
use FFI\CData;
use ReflectionClass;
use ReflectionMethod;
use RuntimeException;
/**
* @method static void bindVertexArray(int $VAO)
* @method static void bindBuffer(int $type, int $VBO)
* @method static void bufferData(int $type, int $size, $data, int $management)
* @method static void viewport(int $x, int $y, int $width, int $height)
* @method static void enableVertexAttribArray(int $VAO)
* @method static void drawArrays(int $type, int $index, int $count)
* @method static void useProgram($shaderProgram)
* @method static void clear(int $type)
* @method static void clearColor(float $red, float $green, float $blue, float $alpha)
* @method static int createShader(int $type)
* @method static void compileShader(int $shader)
* @method static void attachShader(int $program, int $shader)
* @method static int createProgram()
* @method static void linkProgram(int $program)
* @method static void deleteShader(int $shader)
* @method static int getError()
* @method static void enable(int $flag)
* @method static void debugMessageCallback(callable $callback, $userParam)
* @method static void debugMessageControl(int $source, int $type, int $severity, int $count, $null, bool $enabled)
* @method static void blendFunc(int $sfactor, int $bfactor)
*/
class GL extends GLConsts {
public static string $lastCall;
public static FFI $ffi;
@ -47,36 +23,13 @@ class GL extends GLConsts {
*/
public static function init() {
static::$ffi = FFI::load(__DIR__ . "/../headers/gl_generated.h");
$reflection = new ReflectionClass(__CLASS__);
$methods = $reflection->getMethods(
ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_STATIC
);
foreach ($methods as $method) {
if (str_contains($method->getDocComment() ?: "", "@GLIgnore")) {
continue;
}
static::$calls[$method->name] = static::getProcAddress(
$method->name
);
}
preg_match_all(
":@method static [a-zA-Z]+ ([a-zA-Z0-9]+):",
$reflection->getDocComment(),
$matches
);
foreach ($matches[1] as $match) {
static::$calls[$match] = static::getProcAddress($match);
}
include_once __DIR__ . "/gl_functions.php";
}
/**
* @GLIgnore
*/
private static function getProcAddress($name): CData {
public static function getProcAddress($name): CData {
$funcname = 'gl' . ucfirst($name);
$typename = 'FUNC_' . $funcname;
@ -98,211 +51,17 @@ class GL extends GLConsts {
return static::$ffi->cast($typename, $proc);
}
public static function genBuffers(int $amount, &$ids) {
if ($amount > 1) {
$ids = array_fill(0, $amount, 0);
}
if (is_array($ids)) {
$arr = &$ids;
} else {
$arr = [&$ids];
}
$items = static::$ffi->new("GLuint[$amount]");
(static::$calls['genBuffers'])($amount, $items);
for ($i = 0; $i < $amount; $i++) {
$arr[$i] = $items[$i];
}
}
public static function genVertexArrays(int $amount, &$ids) {
if ($amount > 1) {
$ids = array_fill(0, $amount, 0);
}
if (is_array($ids)) {
$arr = &$ids;
} else {
$arr = [&$ids];
}
$items = static::$ffi->new("GLuint[$amount]");
(static::$calls['genVertexArrays'])($amount, $items);
for ($i = 0; $i < $amount; $i++) {
$arr[$i] = $items[$i];
}
}
public static function genTextures(int $amount, &$ids) {
if ($amount > 1) {
$ids = array_fill(0, $amount, 0);
}
if (is_array($ids)) {
$arr = &$ids;
} else {
$arr = [&$ids];
}
$items = static::$ffi->new("GLuint[$amount]");
(static::$calls['genTextures'])($amount, $items);
for ($i = 0; $i < $amount; $i++) {
$arr[$i] = $items[$i];
}
}
/**
* @GLIgnore
*/
public static function __callStatic($name, $arguments) {
if ( ! isset(static::$calls[$name])) {
static::$calls[$name] = static::getProcAddress($name);
}
static::$lastCall = $name;
return (static::$calls[$name])(...$arguments);
}
public static function vertexAttribPointer(
int $index,
int $size,
int $type,
bool $normalized,
int $stride,
int $pointer
) {
$pointerC = static::$ffi->new('long long');
$pointerC->cdata = $pointer;
$p = static::$ffi->cast(
'void*',
$pointerC
);
(static::$calls['vertexAttribPointer'])(
$index,
$size,
$type,
$normalized ? 1 : 0,
$stride,
$p,
);
}
public static function getShaderiv(
int $shader,
int $type,
&$params
) {
$paramsC = static::$ffi->new('GLint');
(static::$calls['getShaderiv'])(
$shader,
$type,
FFI::addr($paramsC)
);
$params = $paramsC->cdata;
}
public static function getProgramiv(
int $program,
int $type,
&$params
) {
$paramsC = static::$ffi->new('GLint');
(static::$calls['getProgramiv'])(
$program,
$type,
FFI::addr($paramsC)
);
$params = $paramsC->cdata;
}
public static function getProgramInfoLog(
int $program,
&$log,
int $maxLength = 512
) {
$logC = static::$ffi->new("char[$maxLength]");
$actualLength = static::$ffi->new("GLsizei");
(static::$calls['getProgramInfoLog'])(
$program,
$maxLength,
FFI::addr($actualLength),
$logC,
);
$log = FFI::string($logC, $actualLength->cdata);
}
public static function getShaderInfoLog(
int $shader,
null|string &$log = null,
int $maxLength = 512
) {
$logC = static::$ffi->new(FFI::arrayType(FFI::type("char"), [$maxLength]));
$actualLength = static::$ffi->new("GLsizei");
(static::$calls['getShaderInfoLog'])(
$shader,
$maxLength,
FFI::addr($actualLength),
$logC,
);
$log = FFI::string($logC, $actualLength->cdata);
}
public static function shaderSource(
int $shader,
int $count,
string $source,
?array $offsets
) {
$item = null;
if (is_array($offsets) && count($offsets) > 0) {
$item = static::$ffi->new('GLint[' . count($offsets) . ']');
for ($i = 0; $i < count($offsets); $i++) {
$item[$i] = $offsets[$i];
}
public static function shaderSource(int $shader, array $sources) {
$lens = [];
$strings = [];
foreach ($sources as $source) {
$strings[] = Utils::string($source, false);
$lens[] = strlen($source);
}
$sourceConst = Utils::constString($source . "\0");
(static::$calls['shaderSource'])(
$shader,
$count,
FFI::addr($sourceConst),
$item,
);
}
/**
* @GLIgnore
*/
public static function getInteger(int $item): int {
return static::getIntegerv($item)[0];
}
public static function getIntegerv(int $item, int $values = 1): array {
$t = static::$ffi->new(FFI::arrayType(static::$ffi->type("GLint"), [$values]));
(static::$calls['getIntegerv'])($item, $t);
$arr = [];
for ($i = 0; $i < $values; $i++) {
$arr[$i] = $t[$i];
}
$arrays = Utils::arrayOf('char*', $strings);
$lengths = Utils::arrayOf('int32_t', $lens);
return $arr;
glShaderSource($shader, count($sources), $arrays, $lengths);
}
}

@ -14,7 +14,7 @@ class Utils {
static function ffi(): FFI {
if (static::$ffi === null) {
static::$ffi = FFI::cdef("");
static::$ffi = FFI::cdef("extern size_t malloc (size_t);");
}
return static::$ffi;
@ -38,12 +38,10 @@ class Utils {
return $arr;
}
public static function string(string $input): FFI\CData {
public static function string(string $input, bool $owned = true): FFI\CData {
$ffi = static::ffi();
$data = $ffi->new('char[' . strlen($input) . ']');
for ($i = 0; $i < strlen($input); $i++) {
$data[$i] = $input[$i];
}
$data = $ffi->new('char[' . strlen($input) . ']', $owned);
FFI::memcpy($data, $input, strlen($input));
return $data;
}
@ -68,13 +66,32 @@ class Utils {
return FFI::sizeof($type);
}
public static function ptr(int $offset): FFI\CData {
$val = GL::$ffi->new("long long", false);
$val->cdata = $offset;
return GL::$ffi->cast('void*', $val);
}
public static function null(): FFI\CData {
if (static::$null === null) {
$val = FFI::new("usize");
$val->cdata = 0;
static::$null = FFI::cast('void *', $val);
if ( ! isset(static::$null)) {
static::$null = self::ptr(0);
}
return static::$null;
}
public static function pointer(&$data = null, $type = null): FFI\CData {
if ($type === null) {
$type = "void*";
}
$data = self::$ffi->new($type);
return FFI::addr($data);
}
public static function stringBuffer(&$infoLog, int $bufSize = 4096) {
return $infoLog = self::$ffi->new('char[' . $bufSize . ']');
}
}

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save