throw all gl functions in global namespace, that'll show them
This commit is contained in:
parent
1f3881bdc4
commit
112b26a4b5
7 changed files with 19183 additions and 3484 deletions
|
@ -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");
|
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 = new DOMDocument();
|
||||||
$xml->loadXML(file_get_contents(__DIR__ . "/../resources/gl.xml"));
|
$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";
|
$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 */
|
/** @var DOMNode $node */
|
||||||
foreach ($commands->childNodes as $node) {
|
foreach ($commands->childNodes as $node) {
|
||||||
if ($node->nodeName !== "command") {
|
if ($node->nodeName !== "command") {
|
||||||
|
@ -26,15 +80,47 @@ foreach ($commands->childNodes as $node) {
|
||||||
$name = $proto->getElementsByTagName("name")[0];
|
$name = $proto->getElementsByTagName("name")[0];
|
||||||
$name->remove();
|
$name->remove();
|
||||||
|
|
||||||
$returnType = trim($proto->textContent);
|
$returnType = trim($proto->textContent);
|
||||||
$functionName = trim($name->textContent);
|
$functionName = trim($name->textContent);
|
||||||
|
|
||||||
$args = [];
|
$args = [];
|
||||||
|
$names = [];
|
||||||
|
$phpArgs = [];
|
||||||
foreach ($node->getElementsByTagName("param") as $param) {
|
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";
|
$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;
|
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");
|
include(__DIR__ . "/../vendor/autoload.php");
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
GL::init();
|
GL::init();
|
||||||
|
|
||||||
|
@ -31,63 +38,66 @@ function main() {
|
||||||
$window,
|
$window,
|
||||||
function($window, $width, $height) use (&$viewportHeight, &$viewportWidth) {
|
function($window, $width, $height) use (&$viewportHeight, &$viewportWidth) {
|
||||||
echo "Size: $width x $height\n";
|
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);
|
$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);
|
}, null);
|
||||||
|
|
||||||
// GL::debugMessageCallback($callback, null);
|
// glDebugMessageCallback($callback, null);
|
||||||
|
|
||||||
GL::enable(GL::DEBUG_OUTPUT);
|
glEnable(GL::DEBUG_OUTPUT);
|
||||||
GL::enable(GL::DEBUG_OUTPUT_SYNCHRONOUS);
|
glEnable(GL::DEBUG_OUTPUT_SYNCHRONOUS);
|
||||||
GL::enable(GL::BLEND);
|
|
||||||
GL::blendFunc(GL::SRC_ALPHA, GL::ONE_MINUS_SRC_ALPHA);
|
|
||||||
|
|
||||||
$vertexShader = GL::createShader(GL::VERTEX_SHADER);
|
glEnable(GL::BLEND);
|
||||||
|
|
||||||
|
// glEnable(GL::BLEND);
|
||||||
|
glBlendFunc(GL::SRC_ALPHA, GL::ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
$vertexShader = \glCreateShader(GL::VERTEX_SHADER);
|
||||||
$vertexShaderSource = file_get_contents(__DIR__ . "/../shaders/vertex.glsl");
|
$vertexShaderSource = file_get_contents(__DIR__ . "/../shaders/vertex.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);
|
if ( ! $success->cdata) {
|
||||||
GL::getShaderiv($vertexShader, GL::COMPILE_STATUS, $success);
|
glGetShaderiv($vertexShader, GL::INFO_LOG_LENGTH, Utils::pointer($logLength, "int32_t"));
|
||||||
|
glGetShaderInfoLog($vertexShader, $logLength, Utils::null(), Utils::stringBuffer($infoLog, $logLength->cdata));
|
||||||
if ( ! $success) {
|
|
||||||
GL::getShaderiv($vertexShader, GL::INFO_LOG_LENGTH, $logLength);
|
|
||||||
GL::getShaderInfoLog($vertexShader, $infoLog, $logLength);
|
|
||||||
die("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n\t$infoLog");
|
die("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n\t$infoLog");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$fragmentShader = GL::createShader(GL::FRAGMENT_SHADER);
|
$fragmentShader = glCreateShader(GL::FRAGMENT_SHADER);
|
||||||
$fragmentShaderSource = file_get_contents(
|
$fragmentShaderSource = file_get_contents(
|
||||||
__DIR__ . "/../shaders/fragment.glsl"
|
__DIR__ . "/../shaders/fragment.glsl"
|
||||||
);
|
);
|
||||||
|
|
||||||
GL::shaderSource($fragmentShader, 1, $fragmentShaderSource, null);
|
GL::shaderSource($fragmentShader, [$fragmentShaderSource]);
|
||||||
GL::compileShader($fragmentShader);
|
glCompileShader($fragmentShader);
|
||||||
GL::getShaderiv($fragmentShader, GL::COMPILE_STATUS, $success);
|
glGetShaderiv($fragmentShader, GL::COMPILE_STATUS, FFI::addr($success));
|
||||||
|
|
||||||
if ( ! $success) {
|
if ( ! $success->cdata) {
|
||||||
GL::getShaderiv($fragmentShader, GL::INFO_LOG_LENGTH, $logLength);
|
glGetShaderiv($fragmentShader, GL::INFO_LOG_LENGTH, Utils::pointer($logLength, "int32_t"));
|
||||||
GL::GetShaderInfoLog($fragmentShader, $infoLog, $logLength);
|
glGetShaderInfoLog($fragmentShader, $logLength->cdata, Utils::pointer($result, 'int32_t'), Utils::stringBuffer($infoLog, $logLength->cdata));
|
||||||
die("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n\t$infoLog");
|
$infoLog = FFI::string($infoLog, $result->cdata);
|
||||||
|
die("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n\t{$infoLog}");
|
||||||
}
|
}
|
||||||
|
|
||||||
$shaderProgram = GL::createProgram();
|
$shaderProgram = glCreateProgram();
|
||||||
GL::attachShader($shaderProgram, $vertexShader);
|
glAttachShader($shaderProgram, $vertexShader);
|
||||||
GL::attachShader($shaderProgram, $fragmentShader);
|
glAttachShader($shaderProgram, $fragmentShader);
|
||||||
GL::linkProgram($shaderProgram);
|
glLinkProgram($shaderProgram);
|
||||||
|
|
||||||
GL::deleteShader($vertexShader);
|
glDeleteShader($vertexShader);
|
||||||
GL::deleteShader($fragmentShader);
|
glDeleteShader($fragmentShader);
|
||||||
|
|
||||||
$vertices = [
|
$vertices = [
|
||||||
-0.5,
|
-0.5,
|
||||||
|
@ -102,20 +112,21 @@ function main() {
|
||||||
];
|
];
|
||||||
|
|
||||||
$float = Utils::arrayOf('float', $vertices);
|
$float = Utils::arrayOf('float', $vertices);
|
||||||
GL::genVertexArrays(1, $VAO);
|
glGenVertexArrays(1, Utils::pointer($VAO, 'uint32_t'));
|
||||||
GL::genBuffers(1, $VBO);
|
glGenBuffers(1, Utils::pointer($VBO, 'uint32_t'));
|
||||||
|
$VAO = $VAO->cdata;
|
||||||
|
$VBO = $VBO->cdata;
|
||||||
|
|
||||||
GL::bindVertexArray($VAO);
|
glBindVertexArray($VAO);
|
||||||
|
glBindBuffer(GL::ARRAY_BUFFER, $VBO);
|
||||||
GL::bindBuffer(GL::ARRAY_BUFFER, $VBO);
|
glBufferData(
|
||||||
GL::bufferData(
|
|
||||||
GL::ARRAY_BUFFER,
|
GL::ARRAY_BUFFER,
|
||||||
FFI::sizeof($float),
|
FFI::sizeof($float),
|
||||||
$float,
|
$float,
|
||||||
GL::STATIC_DRAW
|
GL::STATIC_DRAW
|
||||||
);
|
);
|
||||||
|
|
||||||
GL::vertexAttribPointer(
|
glVertexAttribPointer(
|
||||||
0,
|
0,
|
||||||
3,
|
3,
|
||||||
GL::FLOAT,
|
GL::FLOAT,
|
||||||
|
@ -124,10 +135,10 @@ function main() {
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
GL::enableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
GL::bindBuffer(GL::ARRAY_BUFFER, 0);
|
glBindBuffer(GL::ARRAY_BUFFER, 0);
|
||||||
GL::bindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
$textureRow = Cairo::format_stride_for_width(Cairo::FORMAT_RGB24, 400);
|
$textureRow = Cairo::format_stride_for_width(Cairo::FORMAT_RGB24, 400);
|
||||||
$textureData = FFI::new(FFI::arrayType(FFI::type("unsigned char"), [$textureRow * 400]));
|
$textureData = FFI::new(FFI::arrayType(FFI::type("unsigned char"), [$textureRow * 400]));
|
||||||
|
@ -142,65 +153,57 @@ function main() {
|
||||||
Cairo::fill($cairo);
|
Cairo::fill($cairo);
|
||||||
Cairo::surface_flush($surface);
|
Cairo::surface_flush($surface);
|
||||||
|
|
||||||
Gl::genTextures(1, $texture);
|
glGenTextures(1, Utils::pointer($texture, "uint32_t"));
|
||||||
GL::bindTexture(GL::TEXTURE_2D, $texture);
|
$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)
|
glTexParameteri(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_T, GL::REPEAT);
|
||||||
// set texture filtering parameters
|
// set texture filtering parameters
|
||||||
gl::texParameteri(GL::TEXTURE_2D, GL::TEXTURE_MIN_FILTER, GL::LINEAR);
|
glTexParameteri(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_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");
|
$vertexShaderSource = file_get_contents(__DIR__ . "/../shaders/sq_vertex_shader.glsl");
|
||||||
|
|
||||||
GL::shaderSource(
|
GL::shaderSource($vertexShader, [$vertexShaderSource]);
|
||||||
$vertexShader,
|
|
||||||
1,
|
|
||||||
$vertexShaderSource,
|
|
||||||
null
|
|
||||||
);
|
|
||||||
|
|
||||||
|
glCompileShader($vertexShader);
|
||||||
|
glGetShaderiv($vertexShader, GL::COMPILE_STATUS, Utils::pointer($success, 'int32_t'));
|
||||||
|
|
||||||
GL::compileShader($vertexShader);
|
if ( ! $success->cdata) {
|
||||||
GL::getShaderiv($vertexShader, GL::COMPILE_STATUS, $success);
|
glGetShaderiv($vertexShader, GL::INFO_LOG_LENGTH, Utils::pointer($logLength, "int32_t"));
|
||||||
|
glGetShaderInfoLog($vertexShader, $logLength, Utils::null(), Utils::stringBuffer($infoLog, $logLength->cdata));
|
||||||
if ( ! $success) {
|
|
||||||
GL::getShaderiv($vertexShader, GL::INFO_LOG_LENGTH, $logLength);
|
|
||||||
GL::getShaderInfoLog($vertexShader, $infoLog, $logLength);
|
|
||||||
die("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n\t$infoLog");
|
die("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n\t$infoLog");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$fragmentShader = GL::createShader(GL::FRAGMENT_SHADER);
|
$fragmentShader = glCreateShader(GL::FRAGMENT_SHADER);
|
||||||
$fragmentShaderSource = file_get_contents(
|
$fragmentShaderSource = file_get_contents(
|
||||||
__DIR__ . "/../shaders/sq_fragment_shader.glsl"
|
__DIR__ . "/../shaders/sq_fragment_shader.glsl"
|
||||||
);
|
);
|
||||||
|
|
||||||
GL::shaderSource(
|
GL::shaderSource($fragmentShader, [$fragmentShaderSource]);
|
||||||
$fragmentShader,
|
glCompileShader($fragmentShader);
|
||||||
1,
|
glGetShaderiv($fragmentShader, GL::COMPILE_STATUS, FFI::addr($success));
|
||||||
$fragmentShaderSource,
|
|
||||||
null
|
|
||||||
);
|
|
||||||
GL::compileShader($fragmentShader);
|
|
||||||
GL::getShaderiv($fragmentShader, GL::COMPILE_STATUS, $success);
|
|
||||||
|
|
||||||
if ( ! $success) {
|
|
||||||
GL::getShaderiv($fragmentShader, GL::INFO_LOG_LENGTH, $logLength);
|
if ( ! $success->cdata) {
|
||||||
GL::GetShaderInfoLog($fragmentShader, $infoLog, $logLength);
|
glGetShaderiv($fragmentShader, GL::INFO_LOG_LENGTH, Utils::pointer($logLength, "int32_t"));
|
||||||
die("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n\t$infoLog");
|
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();
|
$squareProgram = glCreateProgram();
|
||||||
GL::attachShader($squareProgram, $vertexShader);
|
glAttachShader($squareProgram, $vertexShader);
|
||||||
GL::attachShader($squareProgram, $fragmentShader);
|
glAttachShader($squareProgram, $fragmentShader);
|
||||||
GL::linkProgram($squareProgram);
|
glLinkProgram($squareProgram);
|
||||||
|
|
||||||
GL::deleteShader($vertexShader);
|
glDeleteShader($vertexShader);
|
||||||
GL::deleteShader($fragmentShader);
|
glDeleteShader($fragmentShader);
|
||||||
|
|
||||||
|
|
||||||
$sq = [
|
$sq = [
|
||||||
|
@ -240,15 +243,18 @@ function main() {
|
||||||
];
|
];
|
||||||
|
|
||||||
$float = Utils::arrayOf('float', $sq);
|
$float = Utils::arrayOf('float', $sq);
|
||||||
GL::genVertexArrays(1, $SQUARE_VAO);
|
glGenVertexArrays(1, Utils::pointer($SQUARE_VAO, 'uint32_t'));
|
||||||
GL::genBuffers(1, $VBO);
|
$SQUARE_VAO = $SQUARE_VAO->cdata;
|
||||||
GL::genBuffers(1, $EBO);
|
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);
|
glBindBuffer(GL::ARRAY_BUFFER, $VBO);
|
||||||
GL::bufferData(
|
glBufferData(
|
||||||
GL::ARRAY_BUFFER,
|
GL::ARRAY_BUFFER,
|
||||||
FFI::sizeof($float),
|
FFI::sizeof($float),
|
||||||
$float,
|
$float,
|
||||||
|
@ -256,46 +262,48 @@ function main() {
|
||||||
);
|
);
|
||||||
|
|
||||||
$indices = Utils::arrayOf("unsigned int", [0, 1, 3, 1, 2, 3]);
|
$indices = Utils::arrayOf("unsigned int", [0, 1, 3, 1, 2, 3]);
|
||||||
GL::bindBuffer(GL::ELEMENT_ARRAY_BUFFER, $EBO);
|
glBindBuffer(GL::ELEMENT_ARRAY_BUFFER, $EBO);
|
||||||
GL::bufferData(
|
glBufferData(
|
||||||
GL::ELEMENT_ARRAY_BUFFER,
|
GL::ELEMENT_ARRAY_BUFFER,
|
||||||
FFI::sizeof($indices),
|
FFI::sizeof($indices),
|
||||||
$indices,
|
$indices,
|
||||||
GL::STATIC_DRAW,
|
GL::STATIC_DRAW,
|
||||||
);
|
);
|
||||||
|
|
||||||
GL::vertexAttribPointer(0, 3, GL::FLOAT, false, 8 * 4, 0);
|
glVertexAttribPointer(0, 3, GL::FLOAT, 0, 8 * 4, 0);
|
||||||
GL::enableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
GL::vertexAttribPointer(1, 3, GL::FLOAT, false, 8 * 4, 3 * 4);
|
glVertexAttribPointer(1, 3, GL::FLOAT, 0, 8 * 4, 3 * 4);
|
||||||
GL::enableVertexAttribArray(1);
|
glEnableVertexAttribArray(1);
|
||||||
GL::vertexAttribPointer(2, 2, GL::FLOAT, false, 8 * 4, 6 * 4);
|
glVertexAttribPointer(2, 2, GL::FLOAT, 0, 8 * 4, 6 * 4);
|
||||||
GL::enableVertexAttribArray(2);
|
glEnableVertexAttribArray(2);
|
||||||
|
|
||||||
GL::useProgram($squareProgram);
|
glUseProgram($squareProgram);
|
||||||
$location = GL::getUniformLocation($squareProgram, "ourTexture");
|
$location = glGetUniformLocation($squareProgram, "ourTexture");
|
||||||
GL::uniform1i($location, 0);
|
glUniform1i($location, 0);
|
||||||
$viewportSizeLocation = GL::getUniformLocation($squareProgram, "viewportSize");
|
$viewportSizeLocation = glGetUniformLocation($squareProgram, "viewportSize");
|
||||||
|
|
||||||
while ( ! GLFW::windowShouldClose($window)) {
|
while ( ! GLFW::windowShouldClose($window)) {
|
||||||
processInput($window);
|
processInput($window);
|
||||||
|
|
||||||
GL::clearColor(0.2, 0.3, 0.3, 1.0);
|
glClearColor(0.2, 0.3, 0.3, 1.0);
|
||||||
GL::clear(GL::COLOR_BUFFER_BIT);
|
glClear(GL::COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
GL::useProgram($shaderProgram);
|
glUseProgram($squareProgram);
|
||||||
GL::bindVertexArray($VAO);
|
|
||||||
GL::drawArrays(GL::TRIANGLES, 0, 3);
|
|
||||||
|
|
||||||
GL::activeTexture(GL::TEXTURE0);
|
glActiveTexture(GL::TEXTURE0);
|
||||||
GL::bindTexture(GL::TEXTURE_2D, $texture);
|
glBindTexture(GL::TEXTURE_2D, $texture);
|
||||||
|
|
||||||
GL::useProgram($squareProgram);
|
glBindVertexArray($VAO);
|
||||||
GL::uniform2i($viewportSizeLocation, $viewportWidth, $viewportHeight);
|
glDrawArrays(GL::TRIANGLES, 0, 3);
|
||||||
GL::bindVertexArray($SQUARE_VAO);
|
|
||||||
|
|
||||||
$f = FFI::new("long long");
|
glActiveTexture(GL::TEXTURE0);
|
||||||
$f->cdata = 0;
|
glBindTexture(GL::TEXTURE_2D, $texture);
|
||||||
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::pollEvents();
|
||||||
GLFW::swapBuffers($window);
|
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()
|
void main()
|
||||||
{
|
{
|
||||||
ivec2 txtSize = textureSize(ourTexture, 0);
|
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);
|
float rest = coord.y - floor(coord.y);
|
||||||
|
|
||||||
FragColor = texture(ourTexture, coord);
|
FragColor = texture(ourTexture, coord);
|
||||||
|
|
263
src/GL.php
263
src/GL.php
|
@ -6,33 +6,9 @@ namespace Cijber\GraphicsToolkit;
|
||||||
use Cijber\GraphicsToolkit\Consts\GLConsts;
|
use Cijber\GraphicsToolkit\Consts\GLConsts;
|
||||||
use FFI;
|
use FFI;
|
||||||
use FFI\CData;
|
use FFI\CData;
|
||||||
use ReflectionClass;
|
|
||||||
use ReflectionMethod;
|
|
||||||
use RuntimeException;
|
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 {
|
class GL extends GLConsts {
|
||||||
public static string $lastCall;
|
public static string $lastCall;
|
||||||
public static FFI $ffi;
|
public static FFI $ffi;
|
||||||
|
@ -47,36 +23,13 @@ class GL extends GLConsts {
|
||||||
*/
|
*/
|
||||||
public static function init() {
|
public static function init() {
|
||||||
static::$ffi = FFI::load(__DIR__ . "/../headers/gl_generated.h");
|
static::$ffi = FFI::load(__DIR__ . "/../headers/gl_generated.h");
|
||||||
|
include_once __DIR__ . "/gl_functions.php";
|
||||||
$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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @GLIgnore
|
* @GLIgnore
|
||||||
*/
|
*/
|
||||||
private static function getProcAddress($name): CData {
|
public static function getProcAddress($name): CData {
|
||||||
$funcname = 'gl' . ucfirst($name);
|
$funcname = 'gl' . ucfirst($name);
|
||||||
$typename = 'FUNC_' . $funcname;
|
$typename = 'FUNC_' . $funcname;
|
||||||
|
|
||||||
|
@ -98,211 +51,17 @@ class GL extends GLConsts {
|
||||||
return static::$ffi->cast($typename, $proc);
|
return static::$ffi->cast($typename, $proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function genBuffers(int $amount, &$ids) {
|
public static function shaderSource(int $shader, array $sources) {
|
||||||
if ($amount > 1) {
|
$lens = [];
|
||||||
$ids = array_fill(0, $amount, 0);
|
$strings = [];
|
||||||
|
foreach ($sources as $source) {
|
||||||
|
$strings[] = Utils::string($source, false);
|
||||||
|
$lens[] = strlen($source);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_array($ids)) {
|
$arrays = Utils::arrayOf('char*', $strings);
|
||||||
$arr = &$ids;
|
$lengths = Utils::arrayOf('int32_t', $lens);
|
||||||
} else {
|
|
||||||
$arr = [&$ids];
|
|
||||||
}
|
|
||||||
|
|
||||||
$items = static::$ffi->new("GLuint[$amount]");
|
glShaderSource($shader, count($sources), $arrays, $lengths);
|
||||||
(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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$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];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $arr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ class Utils {
|
||||||
|
|
||||||
static function ffi(): FFI {
|
static function ffi(): FFI {
|
||||||
if (static::$ffi === null) {
|
if (static::$ffi === null) {
|
||||||
static::$ffi = FFI::cdef("");
|
static::$ffi = FFI::cdef("extern size_t malloc (size_t);");
|
||||||
}
|
}
|
||||||
|
|
||||||
return static::$ffi;
|
return static::$ffi;
|
||||||
|
@ -38,12 +38,10 @@ class Utils {
|
||||||
return $arr;
|
return $arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function string(string $input): FFI\CData {
|
public static function string(string $input, bool $owned = true): FFI\CData {
|
||||||
$ffi = static::ffi();
|
$ffi = static::ffi();
|
||||||
$data = $ffi->new('char[' . strlen($input) . ']');
|
$data = $ffi->new('char[' . strlen($input) . ']', $owned);
|
||||||
for ($i = 0; $i < strlen($input); $i++) {
|
FFI::memcpy($data, $input, strlen($input));
|
||||||
$data[$i] = $input[$i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
@ -68,13 +66,32 @@ class Utils {
|
||||||
return FFI::sizeof($type);
|
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 {
|
public static function null(): FFI\CData {
|
||||||
if (static::$null === null) {
|
if ( ! isset(static::$null)) {
|
||||||
$val = FFI::new("usize");
|
static::$null = self::ptr(0);
|
||||||
$val->cdata = 0;
|
|
||||||
static::$null = FFI::cast('void *', $val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return static::$null;
|
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 . ']');
|
||||||
|
}
|
||||||
}
|
}
|
15822
src/gl_functions.php
Normal file
15822
src/gl_functions.php
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue