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");
|
||||
}
|
||||
|
||||
|
||||
$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);
|
||||
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");
|
||||
|
||||
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/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);
|
||||
glGenVertexArrays(1, Utils::pointer($VAO, 'uint32_t'));
|
||||
glGenBuffers(1, Utils::pointer($VBO, 'uint32_t'));
|
||||
$VAO = $VAO->cdata;
|
||||
$VBO = $VBO->cdata;
|
||||
|
||||
GL::bindVertexArray($VAO);
|
||||
|
||||
GL::bindBuffer(GL::ARRAY_BUFFER, $VBO);
|
||||
GL::bufferData(
|
||||
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);
|
||||
|
||||
GL::useProgram($shaderProgram);
|
||||
GL::bindVertexArray($VAO);
|
||||
GL::drawArrays(GL::TRIANGLES, 0, 3);
|
||||
glUseProgram($squareProgram);
|
||||
|
||||
GL::activeTexture(GL::TEXTURE0);
|
||||
GL::bindTexture(GL::TEXTURE_2D, $texture);
|
||||
glActiveTexture(GL::TEXTURE0);
|
||||
glBindTexture(GL::TEXTURE_2D, $texture);
|
||||
|
||||
GL::useProgram($squareProgram);
|
||||
GL::uniform2i($viewportSizeLocation, $viewportWidth, $viewportHeight);
|
||||
GL::bindVertexArray($SQUARE_VAO);
|
||||
glBindVertexArray($VAO);
|
||||
glDrawArrays(GL::TRIANGLES, 0, 3);
|
||||
|
||||
$f = FFI::new("long long");
|
||||
$f->cdata = 0;
|
||||
GL::drawElements(GL::TRIANGLES, 6, GL::UNSIGNED_INT, FFI::cast('void *', $f));
|
||||
glActiveTexture(GL::TEXTURE0);
|
||||
glBindTexture(GL::TEXTURE_2D, $texture);
|
||||
|
||||
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);
|
||||
|
|
263
src/GL.php
263
src/GL.php
|
@ -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);
|
||||
public static function shaderSource(int $shader, array $sources) {
|
||||
$lens = [];
|
||||
$strings = [];
|
||||
foreach ($sources as $source) {
|
||||
$strings[] = Utils::string($source, false);
|
||||
$lens[] = strlen($source);
|
||||
}
|
||||
|
||||
if (is_array($ids)) {
|
||||
$arr = &$ids;
|
||||
} else {
|
||||
$arr = [&$ids];
|
||||
}
|
||||
$arrays = Utils::arrayOf('char*', $strings);
|
||||
$lengths = Utils::arrayOf('int32_t', $lens);
|
||||
|
||||
$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];
|
||||
}
|
||||
}
|
||||
|
||||
$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;
|
||||
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 . ']');
|
||||
}
|
||||
}
|
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