You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

314 lines
8.8 KiB
PHP

<?php
use Cijber\GraphicsToolkit\Cairo;
use Cijber\GraphicsToolkit\GL;
use Cijber\GraphicsToolkit\GLFW;
use Cijber\GraphicsToolkit\Utils;
include(__DIR__ . "/../vendor/autoload.php");
function main() {
GL::init();
GLFW::init();
GLFW::windowHint(GLFW::CONTEXT_VERSION_MAJOR, 3);
GLFW::windowHint(GLFW::CONTEXT_VERSION_MINOR, 3);
GLFW::windowHint(GLFW::OPENGL_PROFILE, GLFW::OPENGL_CORE_PROFILE);
$window = GLFW::createWindow(800, 600, "Ha it's PHP!", null, null);
if ($window === null || FFI::isNull($window)) {
die("Couldn't create Window");
}
GLFW::makeContextCurrent($window);
$viewportHeight = 0;
$viewportWidth = 0;
GLFW::setFramebufferSizeCallback(
$window,
function($window, $width, $height) use (&$viewportHeight, &$viewportWidth) {
echo "Size: $width x $height\n";
GL::viewport(0, 0, $viewportWidth = $width, $viewportHeight = $height);
}
);
GL::viewport(0, 0, 800, 600);
GL::debugMessageCallback(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]);
}, null);
// GL::debugMessageCallback($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);
$vertexShader = GL::createShader(GL::VERTEX_SHADER);
$vertexShaderSource = file_get_contents(__DIR__ . "/../shaders/vertex.glsl");
GL::shaderSource($vertexShader, 1, $vertexShaderSource, null);
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);
die("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n\t$infoLog");
}
$fragmentShader = GL::createShader(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);
if ( ! $success) {
GL::getShaderiv($fragmentShader, GL::INFO_LOG_LENGTH, $logLength);
GL::GetShaderInfoLog($fragmentShader, $infoLog, $logLength);
die("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n\t$infoLog");
}
$shaderProgram = GL::createProgram();
GL::attachShader($shaderProgram, $vertexShader);
GL::attachShader($shaderProgram, $fragmentShader);
GL::linkProgram($shaderProgram);
GL::deleteShader($vertexShader);
GL::deleteShader($fragmentShader);
$vertices = [
-0.5,
-0.5,
0.0,
0.5,
-0.5,
0.0,
0.0,
0.5,
0.0,
];
$float = Utils::arrayOf('float', $vertices);
GL::genVertexArrays(1, $VAO);
GL::genBuffers(1, $VBO);
GL::bindVertexArray($VAO);
GL::bindBuffer(GL::ARRAY_BUFFER, $VBO);
GL::bufferData(
GL::ARRAY_BUFFER,
FFI::sizeof($float),
$float,
GL::STATIC_DRAW
);
GL::vertexAttribPointer(
0,
3,
GL::FLOAT,
false,
12,
0
);
GL::enableVertexAttribArray(0);
GL::bindBuffer(GL::ARRAY_BUFFER, 0);
GL::bindVertexArray(0);
$textureRow = Cairo::format_stride_for_width(Cairo::FORMAT_RGB24, 400);
$textureData = FFI::new(FFI::arrayType(FFI::type("unsigned char"), [$textureRow * 400]));
$surface = Cairo::image_surface_create_for_data($textureData, Cairo::FORMAT_RGB24, 400, 400, $textureRow);
$cairo = Cairo::create($surface);
Cairo::select_font_face($cairo, "sans-serif", Cairo::FONT_SLANT_NORMAL, Cairo::FONT_SLANT_NORMAL);
Cairo::set_font_size($cairo, 50);
Cairo::move_to($cairo, 50, 50);
Cairo::show_text($cairo, "Hello PHP!");
Cairo::rectangle($cairo, 0, 0, 50, 50);
Cairo::fill($cairo);
Cairo::surface_flush($surface);
Gl::genTextures(1, $texture);
GL::bindTexture(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);
// 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);
GL::texImage2D(GL::TEXTURE_2D, 0, GL::RGBA, 400, 400, 0, GL::BGRA, GL::UNSIGNED_BYTE, $textureData);
$vertexShader = GL::createShader(GL::VERTEX_SHADER);
$vertexShaderSource = file_get_contents(__DIR__ . "/../shaders/sq_vertex_shader.glsl");
GL::shaderSource(
$vertexShader,
1,
$vertexShaderSource,
null
);
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);
die("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n\t$infoLog");
}
$fragmentShader = GL::createShader(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);
if ( ! $success) {
GL::getShaderiv($fragmentShader, GL::INFO_LOG_LENGTH, $logLength);
GL::GetShaderInfoLog($fragmentShader, $infoLog, $logLength);
die("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n\t$infoLog");
}
$squareProgram = GL::createProgram();
GL::attachShader($squareProgram, $vertexShader);
GL::attachShader($squareProgram, $fragmentShader);
GL::linkProgram($squareProgram);
GL::deleteShader($vertexShader);
GL::deleteShader($fragmentShader);
$sq = [
// positions // colors // texture coords
0.5,
0.5,
0.0,
1.0,
0.0,
0.0,
1.0,
1.0, // top right
0.5,
-0.5,
0.0,
0.0,
1.0,
0.0,
1.0,
0.0, // bottom right
-0.5,
-0.5,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0, // bottom left
-0.5,
0.5,
0.0,
1.0,
1.0,
0.0,
0.0,
1.0 // top left
];
$float = Utils::arrayOf('float', $sq);
GL::genVertexArrays(1, $SQUARE_VAO);
GL::genBuffers(1, $VBO);
GL::genBuffers(1, $EBO);
GL::bindVertexArray($SQUARE_VAO);
GL::bindBuffer(GL::ARRAY_BUFFER, $VBO);
GL::bufferData(
GL::ARRAY_BUFFER,
FFI::sizeof($float),
$float,
GL::STATIC_DRAW
);
$indices = Utils::arrayOf("unsigned int", [0, 1, 3, 1, 2, 3]);
GL::bindBuffer(GL::ELEMENT_ARRAY_BUFFER, $EBO);
GL::bufferData(
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);
GL::useProgram($squareProgram);
$location = GL::getUniformLocation($squareProgram, "ourTexture");
GL::uniform1i($location, 0);
$viewportSizeLocation = GL::getUniformLocation($squareProgram, "viewportSize");
while ( ! GLFW::windowShouldClose($window)) {
processInput($window);
GL::clearColor(0.2, 0.3, 0.3, 1.0);
GL::clear(GL::COLOR_BUFFER_BIT);
GL::useProgram($shaderProgram);
GL::bindVertexArray($VAO);
GL::drawArrays(GL::TRIANGLES, 0, 3);
GL::activeTexture(GL::TEXTURE0);
GL::bindTexture(GL::TEXTURE_2D, $texture);
GL::useProgram($squareProgram);
GL::uniform2i($viewportSizeLocation, $viewportWidth, $viewportHeight);
GL::bindVertexArray($SQUARE_VAO);
$f = FFI::new("long long");
$f->cdata = 0;
GL::drawElements(GL::TRIANGLES, 6, GL::UNSIGNED_INT, FFI::cast('void *', $f));
GLFW::pollEvents();
GLFW::swapBuffers($window);
}
GLFW::terminate();
}
function processInput($window) {
if (GLFW::getKey($window, GLFW::KEY_ESCAPE) === GLFW::PRESS) {
GLFW::setWindowShouldClose($window, 1);
}
}
main();