├── .dockerignore ├── .github └── workflows │ └── build-test.yml ├── .gitignore ├── CREDITS ├── Dockerfile ├── LICENSE ├── README.md ├── config.m4 ├── docker-entrypoint.sh ├── examples ├── animation.php ├── basic-shader.php ├── bootstrap.php ├── camera.php ├── composer.json ├── composer.lock ├── fixed-pipeline.php ├── geometry-shader.php ├── lit-model.php ├── lit-obj-model.php ├── models │ ├── cube.obj │ ├── gourd.obj │ ├── pumpkin.obj │ ├── sample.obj │ ├── suzanne.obj │ └── teddy.obj ├── obj-model.php ├── rectangle.php ├── rotate.php ├── shader-effect.php ├── shaders │ ├── basic_lighting.frag │ ├── basic_lighting.vs │ ├── camera.frag │ ├── camera.vert │ ├── geometry-shader.fs │ ├── geometry-shader.gs │ ├── geometry-shader.vs │ ├── lamp.frag │ ├── lamp.vs │ ├── transformations.frag │ └── transformations.vert └── textures │ ├── awesomeface.png │ ├── container.jpg │ ├── sample.png │ └── sample2.png ├── opengl-camera-demo.gif ├── opengl.h ├── package.xml ├── php-sdl.Dockerfile ├── php_convert.c ├── php_convert.h ├── php_opengl.c ├── php_opengl.h └── tests ├── extension-loading.phpt ├── glgeterror_basic.phpt └── glgetstring_basic.phpt /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | -------------------------------------------------------------------------------- /.github/workflows/build-test.yml: -------------------------------------------------------------------------------- 1 | name: Build and test 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | main: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v1 13 | - name: Build and tag SDL image 14 | run: docker build -f php-sdl.Dockerfile -t ponup/php-sdl . 15 | - name: Build and tag image 16 | run: docker build -t ponup/php-opengl . 17 | - name: Run tests 18 | run: docker run --rm ponup/php-opengl 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.lo 3 | *.tgz 4 | config.* 5 | Makefile 6 | Makefile.* 7 | run-tests.php 8 | mkinstalldirs 9 | missing 10 | configure 11 | configure.in 12 | ltmain.sh 13 | build 14 | aclocal.m4 15 | acinclude.m4 16 | *.la 17 | .deps 18 | .libs 19 | install-sh 20 | autom4te.cache 21 | libtool 22 | modules 23 | nbproject 24 | vendor 25 | composer.phar 26 | configure.ac 27 | tests/*.diff 28 | tests/*.exp 29 | tests/*.out 30 | tests/*.log 31 | tests/*.sh 32 | tests/*.php 33 | .DS_Store 34 | .vscode 35 | tags 36 | *.dep 37 | -------------------------------------------------------------------------------- /CREDITS: -------------------------------------------------------------------------------- 1 | PHP-OpenGL 2 | Santiago Lizardo 3 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ponup/php-sdl 2 | 3 | RUN apt-get install -y mesa-common-dev libgl1 libglvnd-dev 4 | COPY . /opt/php-opengl 5 | WORKDIR /opt/php-opengl 6 | RUN phpize && ./configure && make install 7 | RUN echo extension=opengl.so >> /etc/php/8.1/cli/php.ini 8 | 9 | ENTRYPOINT ["/opt/php-opengl/docker-entrypoint.sh"] 10 | 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2022 Santiago Lizardo 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build and test](https://github.com/Ponup/php-opengl/actions/workflows/build-test.yml/badge.svg)](https://github.com/Ponup/php-opengl/actions/workflows/build-test.yml) 2 | 3 | # PHP-OpenGL 4 | 5 | PHP bindings of the OpenGL library. This library allows you to create inmersive 3D applications and games for the desktop with the comfort of the PHP language. 6 | 7 | The extension only supports modern OpenGL and the core profile. The OpenGL compatibility profile (which provides functions such as glRotate, glBegin, glLight, etc...) is not supported. 8 | 9 | [](opengl-camera-demo.gif) 10 | 11 | ## Requirements 12 | 13 | - PHP8.1 14 | - [SDL extension for PHP](https://github.com/Ponup/php-sdl) 15 | - OpenGL library/framework 16 | - Linux/MacOS (Windows support coming soon) 17 | - The PHP GD extension is required to run some of the examples. 18 | 19 | ## Installation 20 | 21 | ### Linux 22 | 23 | ```bash 24 | pecl install opengl-devel 25 | ``` 26 | 27 | Or 28 | 29 | ```bash 30 | git clone git@github.com:Ponup/php-opengl.git --recursive phpopengl 31 | cd php-opengl 32 | phpize 33 | ./configure --with-opengl 34 | make 35 | sudo make install 36 | ``` 37 | 38 | ## Examples 39 | 40 | ```php 41 | type == SDL_KEYDOWN) break; 56 | SDL_Delay(50); 57 | } 58 | 59 | SDL_DestroyWindow($window); 60 | ``` 61 | 62 | Complete examples can be found in the [examples](examples) folder. 63 | 64 | -------------------------------------------------------------------------------- /config.m4: -------------------------------------------------------------------------------- 1 | dnl config.m4 for extension opengl 2 | 3 | PHP_ARG_WITH(opengl, for opengl support, 4 | [ --with-opengl=DIR Include OpenGL support]) 5 | 6 | PHP_ARG_ENABLE(opengl-debug, whether to enable PHP-OpenGL debug support, 7 | [ --enable-opengl-debug Enable OpenGL debug support], no, no) 8 | 9 | CFLAGS="$CFLAGS -Wall -Wfatal-errors" 10 | 11 | if test "$PHP_OPENGL" != "no"; then 12 | 13 | if test -r $PHP_OPENGL/include/GL/gl.h; then 14 | OPENGL_DIR=$PHP_OPENGL 15 | else 16 | AC_MSG_CHECKING(for OpenGL development files in default path) 17 | for i in /usr/X11R6 /usr/local /usr /System/Library/Frameworks/OpenGL.framework/Headers; do 18 | if test -r $i/include/GL/gl.h ; then 19 | OPENGL_DIR=$i 20 | AC_MSG_RESULT(found in $i) 21 | fi 22 | if test -r $i/gl.h ; then 23 | OPENGL_DIR=$i 24 | AC_MSG_RESULT(found in $i) 25 | fi 26 | 27 | done 28 | fi 29 | 30 | if test -z "$OPENGL_DIR"; then 31 | AC_MSG_RESULT(not found) 32 | AC_MSG_ERROR(Please make sure OpenGL is properly installed - gl.h should be in /include/GL/) 33 | fi 34 | 35 | saved_LIBS="$LIBS" 36 | 37 | failed=yes 38 | for additional_libs in "" -lm; do 39 | if test ! -z "$additional_libs"; then 40 | AC_MSG_RESULT(with additional library $additional_libs) 41 | fi 42 | AC_MSG_CHECKING(if OpenGL links properly) 43 | case $build_os in 44 | darwin*) 45 | LIBS="$saved_LIBS -Framework GL $additional_libs" 46 | ;; 47 | *) 48 | LIBS="$saved_LIBS -lGL $additional_libs" 49 | ;; 50 | esac 51 | AC_TRY_LINK( ,[char glBegin(); glBegin(); ], have_GL=yes, have_GL=no) 52 | AC_MSG_RESULT($have_GL) 53 | 54 | if test "$have_GL" = "no"; then 55 | AC_MSG_CHECKING(if MesaGL links properly) 56 | LIBS="$saved_LIBS -lMesaGL $additional_libs" 57 | AC_TRY_LINK( ,[char glBegin(); glBegin(); ], have_MesaGL=yes, have_MesaGL=no) 58 | AC_MSG_RESULT($have_MesaGL) 59 | 60 | if test "$have_MesaGL" = "no"; then 61 | AC_MSG_CHECKING(if MesaGL with pthreads links properly) 62 | LIBS="$saved_LIBS -L$OPENGL_DIR/lib -lMesaGL -lpthread $additional_libs" 63 | AC_TRY_LINK( ,[char glBegin(); glBegin(); ], have_MesaGL_pthreads=yes, have_MesaGL_pthreads=no) 64 | AC_MSG_RESULT($have_MesaGL_pthreads) 65 | 66 | if test "$have_MesaGL_pthreads" != "no"; then 67 | LIBS="$saved_LIBS" 68 | PHP_ADD_LIBRARY_WITH_PATH(pthread, $OPENGL_DIR/lib, OPENGL_SHARED_LIBADD) 69 | PHP_ADD_LIBRARY_WITH_PATH(MesaGL, $OPENGL_DIR/lib, OPENGL_SHARED_LIBADD) 70 | failed=no 71 | fi 72 | else 73 | LIBS="$saved_LIBS" 74 | PHP_ADD_LIBRARY_WITH_PATH(MesaGL, $OPENGL_DIR/lib, OPENGL_SHARED_LIBADD) 75 | failed=no 76 | fi 77 | else 78 | LIBS="$saved_LIBS" 79 | failed=no 80 | fi 81 | if test "$failed" = "no"; then 82 | if test ! -z "$additional_libs"; then 83 | PHP_EVAL_LIBLINE($additional_libs, OPENGL_SHARED_LIBADD) 84 | fi 85 | break 86 | fi 87 | done 88 | if test "$failed" = "yeso"; then 89 | AC_MSG_ERROR(Can't find OpenGL nor MesaGL) 90 | fi 91 | unset additional_libs 92 | 93 | dnl {{{ --enable-opengl-debug 94 | if test "$PHP_OPENGL_DEBUG" != "no"; then 95 | CFLAGS="$CFLAGS -Wall -Wpedantic -g -ggdb -O0" 96 | fi 97 | dnl }}} 98 | 99 | case $build_os in 100 | darwin*) 101 | PHP_ADD_FRAMEWORK(GL) 102 | PHP_ADD_INCLUDE(/System/Library/Frameworks/OpenGL.framework/Headers) 103 | ;; 104 | *) 105 | PHP_ADD_LIBRARY_WITH_PATH(GL, /usr/$PHP_LIBDIR, OPENGL_SHARED_LIBADD) 106 | ;; 107 | esac 108 | 109 | PHP_ADD_INCLUDE($OPENGL_DIR/include) 110 | 111 | PHP_NEW_EXTENSION(opengl, php_convert.c php_opengl.c, $ext_shared) 112 | PHP_SUBST(OPENGL_SHARED_LIBADD) 113 | PHP_ADD_EXTENSION_DEP(opengl, sdl) 114 | 115 | fi 116 | 117 | -------------------------------------------------------------------------------- /docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | Xvfb :99 -screen 0 800x600x24 -ac +extension GLX & 4 | 5 | chmod +x ./run-tests.php 6 | 7 | export DISPLAY=:99 8 | ./run-tests.php -q --show-diff 9 | 10 | killall -9 Xvfb 11 | -------------------------------------------------------------------------------- /examples/animation.php: -------------------------------------------------------------------------------- 1 | load("textures/sample.png", $width, $height); 133 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, $width, $height, 0, GL_RGBA, GL_UNSIGNED_BYTE, $image); 134 | glUniform1i(glGetUniformLocation($shaderProgram, "texKitten"), 0); 135 | 136 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 137 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 138 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 139 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 140 | 141 | glActiveTexture(GL_TEXTURE1); 142 | glBindTexture(GL_TEXTURE_2D, $textures[1]); 143 | $image = $imageLoader->load("textures/sample2.png", $width, $height); 144 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, $width, $height, 0, GL_RGBA, GL_UNSIGNED_BYTE, $image); 145 | glUniform1i(glGetUniformLocation($shaderProgram, "texPuppy"), 1); 146 | 147 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 148 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 149 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 150 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 151 | 152 | $uniModel = glGetUniformLocation($shaderProgram, "model"); 153 | 154 | // Set up projection 155 | $view = Transform::lookAt( 156 | new Vector(1.2, 1.2, 1.2), 157 | new Vector(0.0, 0.0, 0.0), 158 | new Vector(0.0, 0.0, 1.0) 159 | ); 160 | $uniView = glGetUniformLocation($shaderProgram, "view"); 161 | glUniformMatrix4fv($uniView, 1, GL_FALSE, $view->toRowVector()); 162 | 163 | $proj = Transform::perspective((45.0), 800.0 / 600.0, 1.0, 10.0); 164 | $uniProj = glGetUniformLocation($shaderProgram, "proj"); 165 | glUniformMatrix4fv($uniProj, 1, GL_FALSE, $proj->toRowVector()); 166 | 167 | $event = new SDL_Event; 168 | 169 | while(true) { 170 | // Clear the screen to black 171 | glClearColor(0.1, 0.3, 0.3, 1.0); 172 | glClear(GL_COLOR_BUFFER_BIT); 173 | 174 | // Calculate transformation 175 | $t_now = microtime(true); 176 | $time = $t_now - $t_start; 177 | 178 | $model = new Matrix(); 179 | $model = Transform::rotate( 180 | $model, 181 | $time * Angle::toRadians(180.0), 182 | new Vector(0.0, 0.0, 1.0) 183 | ); 184 | glUniformMatrix4fv($uniModel, 1, GL_FALSE, $model->toRowVector()); 185 | 186 | // Draw a rectangle from the 2 triangles using 6 indices 187 | glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, null); 188 | 189 | // Swap buffers 190 | SDL_GL_SwapWindow($window); 191 | 192 | SDL_PollEvent($event); 193 | if($event->type == SDL_KEYDOWN) break; 194 | 195 | SDL_Delay(20); 196 | } 197 | 198 | glDeleteTextures(2, $textures); 199 | 200 | glDeleteProgram($shaderProgram); 201 | glDeleteShader($fragmentShader); 202 | glDeleteShader($vertexShader); 203 | 204 | glDeleteBuffers(1, $ebo); 205 | glDeleteBuffers(1, $vbo); 206 | 207 | glDeleteVertexArrays(1, $vao); 208 | 209 | -------------------------------------------------------------------------------- /examples/basic-shader.php: -------------------------------------------------------------------------------- 1 | type == SDL_KEYDOWN) break; 110 | 111 | SDL_Delay(50); 112 | } 113 | 114 | 115 | glDeleteProgram($shaderProgram); 116 | glDeleteShader($fragmentShader); 117 | glDeleteShader($vertexShader); 118 | 119 | glDeleteBuffers(1, $ebo); 120 | glDeleteBuffers(1, $vbo); 121 | 122 | glDeleteVertexArrays(1, $vao); 123 | 124 | -------------------------------------------------------------------------------- /examples/bootstrap.php: -------------------------------------------------------------------------------- 1 | add($cameraFront->scale($cameraSpeed)); 43 | } 44 | if ($keys['s']) { 45 | $cameraPos = $cameraPos->substract($cameraFront->scale($cameraSpeed)); 46 | } 47 | if ($keys['a']) { 48 | $cameraPos = $cameraPos->substract( 49 | $cameraFront->cross($cameraUp)->normalize()->scale($cameraSpeed) 50 | ); 51 | } 52 | if ($keys['d']) { 53 | $cameraPos = $cameraPos->add( 54 | $cameraFront->cross($cameraUp)->normalize()->scale($cameraSpeed) 55 | ); 56 | } 57 | } 58 | $scroll_callback = function ($wheel, $direction, $x, $y) { 59 | $fov = &$GLOBALS['fov']; 60 | if ($fov >= 1.0 && $fov <= 45.0) 61 | $fov -= $direction; 62 | if ($fov <= 1.0) 63 | $fov = 1.0; 64 | if ($fov >= 45.0) 65 | $fov = 45.0; 66 | }; 67 | $motion_callback = function ($xpos, $ypos) use(&$lastMouseCoordinates) { 68 | $yaw = &$GLOBALS['yaw']; 69 | $pitch = &$GLOBALS['pitch']; 70 | 71 | if (null === $lastMouseCoordinates) { 72 | $lastMouseCoordinates = new Vector($xpos-(WIDTH>>1), $ypos+(HEIGHT>>1)); 73 | } 74 | 75 | $xoffset = $xpos - $lastMouseCoordinates->x; 76 | $yoffset = $lastMouseCoordinates->y - $ypos; // Reversed since y-coordinates go from bottom to left 77 | $lastMouseCoordinates = new Vector($xpos, $ypos); 78 | 79 | $sensitivity = 0.1; // Change this value to your liking 80 | $xoffset *= $sensitivity; 81 | $yoffset *= $sensitivity; 82 | 83 | $yaw += $xoffset; 84 | $pitch += $yoffset; 85 | 86 | // Make sure that when pitch is out of bounds, screen doesn't get flipped 87 | if ($pitch > 89.0) 88 | $pitch = 89.0; 89 | if ($pitch < -89.0) 90 | $pitch = -89.0; 91 | 92 | $front = new Vector( 93 | cos(Angle::toRadians($yaw)) * cos(Angle::toRadians($pitch)), 94 | sin(Angle::toRadians($pitch)), 95 | sin(Angle::toRadians($yaw)) * cos(Angle::toRadians($pitch)) 96 | ); 97 | $GLOBALS['cameraFront'] = $front->normalize(); 98 | }; 99 | 100 | SDL_Init(SDL_INIT_EVERYTHING); 101 | 102 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); 103 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); 104 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); 105 | 106 | $window = SDL_CreateWindow("Fixed pipeline example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH, HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); 107 | SDL_GL_CreateContext($window); 108 | 109 | // Define the viewport dimensions 110 | glViewport(0, 0, WIDTH, HEIGHT); 111 | 112 | glEnable(GL_DEPTH_TEST); 113 | //glDepthFunc(GL_LESS); 114 | 115 | //glFrontFace(GL_CCW);; 116 | 117 | // Build and compile our shader program 118 | $shaderProgram = new Shader\Program; 119 | $shaderProgram->add(new Shader\Vertex("shaders/camera.vert")); 120 | $shaderProgram->add(new Shader\Fragment("shaders/camera.frag")); 121 | $shaderProgram->compile(); 122 | $shaderProgram->link(); 123 | 124 | // Set up vertex data (and buffer(s)) and attribute pointers 125 | $vertices = [ 126 | -0.5, -0.5, -0.5, 0.0, 0.0, 127 | 0.5, -0.5, -0.5, 1.0, 0.0, 128 | 0.5, 0.5, -0.5, 1.0, 1.0, 129 | 0.5, 0.5, -0.5, 1.0, 1.0, 130 | -0.5, 0.5, -0.5, 0.0, 1.0, 131 | -0.5, -0.5, -0.5, 0.0, 0.0, 132 | 133 | -0.5, -0.5, 0.5, 0.0, 0.0, 134 | 0.5, -0.5, 0.5, 1.0, 0.0, 135 | 0.5, 0.5, 0.5, 1.0, 1.0, 136 | 0.5, 0.5, 0.5, 1.0, 1.0, 137 | -0.5, 0.5, 0.5, 0.0, 1.0, 138 | -0.5, -0.5, 0.5, 0.0, 0.0, 139 | 140 | -0.5, 0.5, 0.5, 1.0, 0.0, 141 | -0.5, 0.5, -0.5, 1.0, 1.0, 142 | -0.5, -0.5, -0.5, 0.0, 1.0, 143 | -0.5, -0.5, -0.5, 0.0, 1.0, 144 | -0.5, -0.5, 0.5, 0.0, 0.0, 145 | -0.5, 0.5, 0.5, 1.0, 0.0, 146 | 147 | 0.5, 0.5, 0.5, 1.0, 0.0, 148 | 0.5, 0.5, -0.5, 1.0, 1.0, 149 | 0.5, -0.5, -0.5, 0.0, 1.0, 150 | 0.5, -0.5, -0.5, 0.0, 1.0, 151 | 0.5, -0.5, 0.5, 0.0, 0.0, 152 | 0.5, 0.5, 0.5, 1.0, 0.0, 153 | 154 | -0.5, -0.5, -0.5, 0.0, 1.0, 155 | 0.5, -0.5, -0.5, 1.0, 1.0, 156 | 0.5, -0.5, 0.5, 1.0, 0.0, 157 | 0.5, -0.5, 0.5, 1.0, 0.0, 158 | -0.5, -0.5, 0.5, 0.0, 0.0, 159 | -0.5, -0.5, -0.5, 0.0, 1.0, 160 | 161 | -0.5, 0.5, -0.5, 0.0, 1.0, 162 | 0.5, 0.5, -0.5, 1.0, 1.0, 163 | 0.5, 0.5, 0.5, 1.0, 0.0, 164 | 0.5, 0.5, 0.5, 1.0, 0.0, 165 | -0.5, 0.5, 0.5, 0.0, 0.0, 166 | -0.5, 0.5, -0.5, 0.0, 1.0 167 | ]; 168 | 169 | $cubePositions = [ 170 | new Vector(0.0, 0.0, 0.0), 171 | new Vector(2.0, 5.0, -15.0), 172 | new Vector(-1.5, -2.2, -2.5), 173 | new Vector(-3.8, -2.0, -12.3), 174 | new Vector(2.4, -0.4, -3.5), 175 | new Vector(-1.7, 3.0, -7.5), 176 | new Vector(1.3, -2.0, -2.5), 177 | new Vector(1.5, 2.0, -2.5), 178 | new Vector(1.5, 0.2, -1.5), 179 | new Vector(-1.3, 1.0, -1.5) 180 | ]; 181 | 182 | glGenVertexArrays(1, $VAOS); 183 | $VAO = $VAOS[0]; 184 | glGenBuffers(1, $VBOS); 185 | $VBO = $VBOS[0]; 186 | 187 | glBindVertexArray($VAO); 188 | 189 | glBindBuffer(GL_ARRAY_BUFFER, $VBO); 190 | glBufferData(GL_ARRAY_BUFFER, sizeof($vertices) * 4, $vertices, GL_STATIC_DRAW); 191 | 192 | // Position attribute 193 | glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * 4, 0); 194 | glEnableVertexAttribArray(0); 195 | // TexCoord attribute 196 | glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * 4, (3 * 4)); 197 | glEnableVertexAttribArray(2); 198 | 199 | glBindVertexArray(0); // Unbind VAO 200 | 201 | $imageLoader = new ImageLoader; 202 | 203 | // Load and create a texture 204 | $textures = []; 205 | // ==================== 206 | // Texture 1 207 | // ==================== 208 | glGenTextures(1, $textures); 209 | $texture1 = $textures[0]; 210 | glBindTexture(GL_TEXTURE_2D, $texture1); // All upcoming GL_TEXTURE_2D operations now have effect on our texture object 211 | // Set our texture parameters 212 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture wrapping to GL_REPEAT 213 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 214 | // Set texture filtering 215 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 216 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 217 | // Load, create texture and generate mipmaps 218 | $image = $imageLoader->load("textures/container.jpg", $width, $height); 219 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, $width, $height, 0, GL_BGRA, GL_UNSIGNED_BYTE, $image); 220 | glGenerateMipmap(GL_TEXTURE_2D); 221 | glBindTexture(GL_TEXTURE_2D, 0); // Unbind texture when done, so we won't accidentily mess up our texture. 222 | // =================== 223 | // Texture 2 224 | // =================== 225 | $textures2 = []; 226 | glGenTextures(1, $textures2); 227 | $texture2 = $textures2[0]; 228 | glBindTexture(GL_TEXTURE_2D, $texture2); 229 | // Set our texture parameters 230 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 231 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 232 | // Set texture filtering 233 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 234 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 235 | // Load, create texture and generate mipmaps 236 | $image = $imageLoader->load("textures/awesomeface.png", $width, $height); 237 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, $width, $height, 0, GL_BGRA, GL_UNSIGNED_BYTE, $image); 238 | glGenerateMipmap(GL_TEXTURE_2D); 239 | glBindTexture(GL_TEXTURE_2D, 0); 240 | 241 | $event = new SDL_Event; 242 | 243 | $quit = false; 244 | 245 | // Game loop 246 | while (!$quit) { 247 | // Calculate deltatime of current frame 248 | $currentFrame = microtime(true); 249 | $deltaTime = $currentFrame - $lastFrame; 250 | $lastFrame = $currentFrame; 251 | 252 | while (SDL_PollEvent($event)) { 253 | switch ($event->type) { 254 | case SDL_MOUSEMOTION: 255 | $motion_callback($event->motion->x, $event->motion->y); 256 | break; 257 | case SDL_KEYDOWN: 258 | $symChar = chr($event->key->keysym->sym); 259 | $keys['w'] = $symChar == 'w'; 260 | $keys['s'] = $symChar == 's'; 261 | $keys['a'] = $symChar == 'a'; 262 | $keys['d'] = $symChar == 'd'; 263 | break; 264 | case SDL_KEYUP: 265 | $keys = array_fill_keys(range('a', 'z'), false); 266 | break; 267 | case SDL_QUIT: 268 | $quit = true; 269 | break; 270 | } 271 | } 272 | 273 | // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions 274 | updateCameraPosition(); 275 | 276 | // Render 277 | // Clear the colorbuffer 278 | glClearColor(0.2, 0.3, 0.3, 1.0); 279 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 280 | 281 | // Bind Textures using texture units 282 | glActiveTexture(GL_TEXTURE0); 283 | glBindTexture(GL_TEXTURE_2D, $texture1); 284 | glUniform1i(glGetUniformLocation($shaderProgram->getId(), "ourTexture1"), 0); 285 | glActiveTexture(GL_TEXTURE1); 286 | glBindTexture(GL_TEXTURE_2D, $texture2); 287 | glUniform1i(glGetUniformLocation($shaderProgram->getId(), "ourTexture2"), 1); 288 | 289 | // Activate shader 290 | $shaderProgram->Use(); 291 | 292 | // Projection 293 | $projection = Transform::perspective($fov, (float)WIDTH / (float)HEIGHT, 0.1, 100.0); 294 | // Get the uniform locations 295 | 296 | // Camera/View transformation 297 | $view = Transform::lookAt($cameraPos, $cameraPos->add($cameraFront), $cameraUp); 298 | 299 | $modelLoc = glGetUniformLocation($shaderProgram->getId(), "model"); 300 | $viewLoc = glGetUniformLocation($shaderProgram->getId(), "view"); 301 | $projLoc = glGetUniformLocation($shaderProgram->getId(), "projection"); 302 | // Pass the matrices to the shader 303 | glUniformMatrix4fv($viewLoc, 1, GL_FALSE, $view->toRowVector()); 304 | glUniformMatrix4fv($projLoc, 1, GL_FALSE, $projection->toRowVector()); 305 | 306 | glBindVertexArray($VAO); 307 | for ($i = 0; $i < count($cubePositions); $i++) { 308 | // Calculate the model matrix for each object and pass it to shader before drawing 309 | $model = new Matrix(); 310 | $model = Transform::translate($model, $cubePositions[$i]); 311 | $angle = 20.0 * $i; 312 | $model = Transform::rotate($model, $angle, new Vector(1.0, 0.3, 0.5)); 313 | glUniformMatrix4fv($modelLoc, 1, GL_FALSE, $model->toRowVector()); 314 | 315 | glDrawArrays(GL_TRIANGLES, 0, 36); 316 | } 317 | glBindVertexArray(0); 318 | 319 | // Swap the screen buffers 320 | SDL_GL_SwapWindow($window); 321 | } 322 | 323 | glDeleteVertexArrays(1, $VAO); 324 | glDeleteBuffers(1, $VBO); 325 | -------------------------------------------------------------------------------- /examples/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "ponup/mammoth": "dev-master" 4 | }, 5 | "minimum-stability": "dev", 6 | "prefer-stable": true 7 | } 8 | -------------------------------------------------------------------------------- /examples/composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "16bc4c38c63c2d2779948edfe915decc", 8 | "packages": [ 9 | { 10 | "name": "ponup/mammoth", 11 | "version": "dev-master", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/Ponup/mammoth-framework.git", 15 | "reference": "736fc837106bc3a953abefb6d8578c10d829020e" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/Ponup/mammoth-framework/zipball/736fc837106bc3a953abefb6d8578c10d829020e", 20 | "reference": "736fc837106bc3a953abefb6d8578c10d829020e", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": "^8.2" 25 | }, 26 | "require-dev": { 27 | "phpunit/phpunit": "^9" 28 | }, 29 | "default-branch": true, 30 | "type": "library", 31 | "autoload": { 32 | "psr-4": { 33 | "Mammoth\\": "src" 34 | } 35 | }, 36 | "notification-url": "https://packagist.org/downloads/", 37 | "description": "Mammoth framework - Multimedia with PHP", 38 | "support": { 39 | "issues": "https://github.com/Ponup/mammoth-framework/issues", 40 | "source": "https://github.com/Ponup/mammoth-framework/tree/master" 41 | }, 42 | "time": "2023-01-01T16:32:49+00:00" 43 | } 44 | ], 45 | "packages-dev": [], 46 | "aliases": [], 47 | "minimum-stability": "dev", 48 | "stability-flags": { 49 | "ponup/mammoth": 20 50 | }, 51 | "prefer-stable": true, 52 | "prefer-lowest": false, 53 | "platform": [], 54 | "platform-dev": [], 55 | "plugin-api-version": "2.1.0" 56 | } 57 | -------------------------------------------------------------------------------- /examples/fixed-pipeline.php: -------------------------------------------------------------------------------- 1 | type == SDL_KEYDOWN) break; 18 | SDL_Delay(50); 19 | } 20 | 21 | SDL_DestroyWindow($window); 22 | 23 | -------------------------------------------------------------------------------- /examples/geometry-shader.php: -------------------------------------------------------------------------------- 1 | add(new Shader\Vertex("shaders/geometry-shader.vs")); 27 | $shaderProgram->add(new Shader\Fragment("shaders/geometry-shader.fs")); 28 | $shaderProgram->add(new Shader\Geometry("shaders/geometry-shader.gs")); 29 | $shaderProgram->compile(); 30 | $shaderProgram->link(); 31 | 32 | // set up vertex data (and buffer(s)) and configure vertex attributes 33 | $points = [ 34 | -0.5, 0.5, 1.0, 0.0, 0.0, // top-left 35 | 0.5, 0.5, 0.0, 1.0, 0.0, // top-right 36 | 0.5, -0.5, 0.0, 0.0, 1.0, // bottom-right 37 | -0.5, -0.5, 1.0, 1.0, 0.0 // bottom-left 38 | ]; 39 | const SizeOfFloat = 4; 40 | 41 | glGenBuffers(1, $VBOS); 42 | $VBO = $VBOS[0]; 43 | glGenVertexArrays(1, $VAOS); 44 | $VAO = $VAOS[0]; 45 | 46 | glBindVertexArray($VAO); 47 | glBindBuffer(GL_ARRAY_BUFFER, $VBO); 48 | glBufferData(GL_ARRAY_BUFFER, sizeof($points), $points, GL_STATIC_DRAW); 49 | glEnableVertexAttribArray(0); 50 | glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * SizeOfFloat, 0); 51 | glEnableVertexAttribArray(1); 52 | glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * SizeOfFloat, (2 * SizeOfFloat)); 53 | glBindVertexArray(0); 54 | 55 | $shaderProgram->use(); 56 | 57 | $quit = false; 58 | $event = new SDL_Event; 59 | while (!$quit) { 60 | glClearColor(0.1, 0.1, 0.1, 1.0); 61 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 62 | 63 | glBindVertexArray($VAO); 64 | glDrawArrays(GL_POINTS, 0, 4); 65 | 66 | SDL_GL_SwapWindow($window); 67 | 68 | SDL_Delay(10); 69 | while(SDL_PollEvent($event)) { 70 | if($event->type == SDL_QUIT) $quit = true; 71 | } 72 | } 73 | 74 | glDeleteVertexArrays(1, $VAO); 75 | glDeleteBuffers(1, $VBO); 76 | -------------------------------------------------------------------------------- /examples/lit-model.php: -------------------------------------------------------------------------------- 1 | add(new Shader\Vertex("shaders/basic_lighting.vs")); 47 | $lightingShader->add(new Shader\Fragment("shaders/basic_lighting.frag")); 48 | $lightingShader->compile(); 49 | $lightingShader->link(); 50 | 51 | $lampShader = new shader\Program; 52 | $lampShader->add(new Shader\Vertex("shaders/lamp.vs")); 53 | $lampShader->add(new Shader\Fragment("shaders/lamp.frag")); 54 | $lampShader->compile(); 55 | $lampShader->link(); 56 | 57 | $mouse_callback = function($xpos, $ypos) 58 | { 59 | global $camera; 60 | $lastX = &$GLOBALS['lastX']; 61 | $lastY = &$GLOBALS['lastY']; 62 | static $firstMouse = true; 63 | if ($firstMouse) 64 | { 65 | $lastX = $xpos; 66 | $lastY = $ypos; 67 | $firstMouse = false; 68 | } 69 | 70 | $xoffset = $xpos - $lastX; 71 | $yoffset = $lastY - $ypos; // Reversed since y-coordinates go from bottom to left 72 | 73 | $lastX = $xpos; 74 | $lastY = $ypos; 75 | 76 | $camera->ProcessMouseMovement($xoffset, $yoffset); 77 | }; 78 | 79 | // Set up vertex data (and buffer(s)) and attribute pointers 80 | $vertices = [ 81 | -0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 82 | 0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 83 | 0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 84 | 0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 85 | -0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 86 | -0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 87 | 88 | -0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 89 | 0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 90 | 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 91 | 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 92 | -0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 93 | -0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 94 | 95 | -0.5, 0.5, 0.5, -1.0, 0.0, 0.0, 96 | -0.5, 0.5, -0.5, -1.0, 0.0, 0.0, 97 | -0.5, -0.5, -0.5, -1.0, 0.0, 0.0, 98 | -0.5, -0.5, -0.5, -1.0, 0.0, 0.0, 99 | -0.5, -0.5, 0.5, -1.0, 0.0, 0.0, 100 | -0.5, 0.5, 0.5, -1.0, 0.0, 0.0, 101 | 102 | 0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 103 | 0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 104 | 0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 105 | 0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 106 | 0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 107 | 0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 108 | 109 | -0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 110 | 0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 111 | 0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 112 | 0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 113 | -0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 114 | -0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 115 | 116 | -0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 117 | 0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 118 | 0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 119 | 0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 120 | -0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 121 | -0.5, 0.5, -0.5, 0.0, 1.0, 0.0 122 | ]; 123 | // First, set the container's VAO (and VBO) 124 | glGenVertexArrays(1, $containerVAOS); $containerVAO = $containerVAOS[0]; 125 | glGenBuffers(1, $VBOS); $VBO = $VBOS[0]; 126 | 127 | glBindBuffer(GL_ARRAY_BUFFER, $VBO); 128 | glBufferData(GL_ARRAY_BUFFER, sizeof($vertices) * 4, $vertices, GL_STATIC_DRAW); 129 | 130 | glBindVertexArray($containerVAO); 131 | // Position attribute 132 | glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * 4, 0); 133 | glEnableVertexAttribArray(0); 134 | // Normal attribute 135 | glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * 4, (3 * 4)); 136 | glEnableVertexAttribArray(1); 137 | glBindVertexArray(0); 138 | 139 | // Then, we set the light's VAO (VBO stays the same. After all, the vertices are the same for the light object (also a 3D cube)) 140 | glGenVertexArrays(1, $lightVAOS); $lightVAO = $lightVAOS[0]; 141 | glBindVertexArray($lightVAO); 142 | // We only need to bind to the VBO (to link it with glVertexAttribPointer), no need to fill it; the VBO's data already contains all we need. 143 | glBindBuffer(GL_ARRAY_BUFFER, $VBO); 144 | // Set the vertex attributes (only position data for the lamp)) 145 | glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * 4, 0); // Note that we skip over the normal vectors 146 | glEnableVertexAttribArray(0); 147 | glBindVertexArray(0); 148 | 149 | $event = new SDL_Event; 150 | 151 | while(true) { 152 | // Calculate deltatime of current frame 153 | $currentFrame = microtime(true); 154 | $deltaTime = $currentFrame - $lastFrame; 155 | $lastFrame = $currentFrame; 156 | 157 | // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions 158 | do_movement(); 159 | 160 | // Clear the colorbuffer 161 | glClearColor(0.1, 0.1, 0.1, 1.0); 162 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 163 | 164 | // Use cooresponding shader when setting uniforms/drawing objects 165 | $lightingShader->Use(); 166 | $objectColorLoc = glGetUniformLocation($lightingShader->getId(), "objectColor"); 167 | glUniform3f($objectColorLoc, 1.0, .5, 0.31); 168 | $lightColorLoc = glGetUniformLocation($lightingShader->getId(), "lightColor"); 169 | glUniform3f($lightColorLoc, 1.0, 1.0, 1.0); 170 | $lightPosLoc = glGetUniformLocation($lightingShader->getId(), "lightPos"); 171 | glUniform3f($lightPosLoc, $lightPos->x, $lightPos->y, $lightPos->z); 172 | $viewPosLoc = glGetUniformLocation($lightingShader->getId(), "viewPos"); 173 | glUniform3f($viewPosLoc, $camera->position->x, $camera->position->y, $camera->position->z); 174 | 175 | // Create camera transformations 176 | $view = new Matrix(); 177 | $view = $camera->GetViewMatrix(); 178 | $projection = Transform::perspective($camera->zoom, floatval(WIDTH / HEIGHT), 0.1, 100.0); 179 | // Get the uniform locations 180 | $modelLoc = glGetUniformLocation($lightingShader->getId(), "model"); 181 | $viewLoc = glGetUniformLocation($lightingShader->getId(), "view"); 182 | $projLoc = glGetUniformLocation($lightingShader->getId(), "projection"); 183 | // Pass the matrices to the shader 184 | glUniformMatrix4fv($viewLoc, 1, GL_FALSE, $view->toRowVector()); 185 | glUniformMatrix4fv($projLoc, 1, GL_FALSE, $projection->toRowVector()); 186 | 187 | // Draw the container (using container's vertex attributes) 188 | glBindVertexArray($containerVAO); 189 | $model = new Matrix(); 190 | glUniformMatrix4fv($modelLoc, 1, GL_FALSE, $model->toRowVector()); 191 | glDrawArrays(GL_TRIANGLES, 0, 36); 192 | glBindVertexArray(0); 193 | 194 | // Also draw the lamp object, again binding the appropriate shader 195 | $lampShader->Use(); 196 | // Get location objects for the matrices on the lamp shader (these could be different on a different shader) 197 | $modelLoc = glGetUniformLocation($lampShader->getId(), "model"); 198 | $viewLoc = glGetUniformLocation($lampShader->getId(), "view"); 199 | $projLoc = glGetUniformLocation($lampShader->getId(), "projection"); 200 | // Set matrices 201 | glUniformMatrix4fv($viewLoc, 1, GL_FALSE, $view->toRowVector()); 202 | glUniformMatrix4fv($projLoc, 1, GL_FALSE, $projection->toRowVector()); 203 | $model = new Matrix; 204 | $model = Transform::translate($model, $lightPos); 205 | $model = $model->scale(0.2); // Make it a smaller cube 206 | glUniformMatrix4fv($modelLoc, 1, GL_FALSE, $model->toRowVector()); 207 | // Draw the light object (using light's vertex attributes) 208 | glBindVertexArray($lightVAO); 209 | glDrawArrays(GL_TRIANGLES, 0, 36); 210 | glBindVertexArray(0); 211 | 212 | // Swap the screen buffers 213 | SDL_GL_SwapWindow($window); 214 | while(SDL_PollEvent($event)) { 215 | switch($event->type) { 216 | case SDL_MOUSEMOTION: 217 | $mouse_callback($event->motion->x, $event->motion->y); 218 | break; 219 | case SDL_KEYDOWN: 220 | $symChar = chr($event->key->keysym->sym); 221 | $keys['w'] = $symChar == 'w'; 222 | $keys['s'] = $symChar == 's'; 223 | $keys['a'] = $symChar == 'a'; 224 | $keys['d'] = $symChar == 'd'; 225 | break; 226 | case SDL_KEYUP: 227 | $keys = array_fill_keys(range('a', 'z'), false); 228 | break; 229 | } 230 | } 231 | 232 | 233 | SDL_Delay(10); 234 | } 235 | 236 | function do_movement() 237 | { 238 | global $deltaTime; 239 | $camera = &$GLOBALS['camera']; 240 | $keys = &$GLOBALS['keys']; 241 | // Camera controls 242 | if ($keys['w']) { 243 | $camera->ProcessKeyboard(Camera::FORWARD, $deltaTime); 244 | } 245 | if ($keys['s']) { 246 | $camera->ProcessKeyboard(Camera::BACKWARD, $deltaTime); 247 | } 248 | if ($keys['a']) { 249 | $camera->ProcessKeyboard(Camera::LEFT, $deltaTime); 250 | } 251 | if ($keys['d']) { 252 | $camera->ProcessKeyboard(Camera::RIGHT, $deltaTime); 253 | } 254 | } 255 | 256 | -------------------------------------------------------------------------------- /examples/lit-obj-model.php: -------------------------------------------------------------------------------- 1 | ProcessMouseMovement($xoffset, $yoffset); 45 | }; 46 | 47 | 48 | // Light attributes 49 | $lightPos = new Vector(1.2, 1.0, 2.0); 50 | 51 | // Deltatime 52 | $deltaTime = 0.0; // Time between current frame and last frame 53 | $lastFrame = 0.0; // Time of last frame 54 | 55 | SDL_Init(SDL_INIT_EVERYTHING); 56 | 57 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); 58 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); 59 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); 60 | 61 | $window = SDL_CreateWindow("Fixed pipeline example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); 62 | SDL_GL_CreateContext($window); 63 | 64 | // Define the viewport dimensions 65 | glViewport(0, 0, WIDTH, HEIGHT); 66 | 67 | // OpenGL options 68 | glEnable(GL_DEPTH_TEST); 69 | 70 | $lightingShader = new Shader\Program; 71 | $lightingShader->add(new Shader\Vertex("shaders/basic_lighting.vs")); 72 | $lightingShader->add(new Shader\Fragment("shaders/basic_lighting.frag")); 73 | $lightingShader->compile(); 74 | $lightingShader->link(); 75 | 76 | $lampShader = new shader\Program; 77 | $lampShader->add(new Shader\Vertex("shaders/lamp.vs")); 78 | $lampShader->add(new Shader\Fragment("shaders/lamp.frag")); 79 | $lampShader->compile(); 80 | $lampShader->link(); 81 | 82 | $lightvertices = [ 83 | -0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 84 | 0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 85 | 0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 86 | 0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 87 | -0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 88 | -0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 89 | 90 | -0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 91 | 0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 92 | 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 93 | 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 94 | -0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 95 | -0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 96 | 97 | -0.5, 0.5, 0.5, -1.0, 0.0, 0.0, 98 | -0.5, 0.5, -0.5, -1.0, 0.0, 0.0, 99 | -0.5, -0.5, -0.5, -1.0, 0.0, 0.0, 100 | -0.5, -0.5, -0.5, -1.0, 0.0, 0.0, 101 | -0.5, -0.5, 0.5, -1.0, 0.0, 0.0, 102 | -0.5, 0.5, 0.5, -1.0, 0.0, 0.0, 103 | 104 | 0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 105 | 0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 106 | 0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 107 | 0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 108 | 0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 109 | 0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 110 | 111 | -0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 112 | 0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 113 | 0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 114 | 0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 115 | -0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 116 | -0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 117 | 118 | -0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 119 | 0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 120 | 0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 121 | 0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 122 | -0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 123 | -0.5, 0.5, -0.5, 0.0, 1.0, 0.0 124 | ]; 125 | 126 | $loader = new WavefrontObjLoader; 127 | $obj = $loader->load($argc === 2 ? $argv[1] : 'models/pumpkin.obj'); 128 | 129 | // Set up vertex data (and buffer(s)) and attribute pointers 130 | $verticesVectors = $obj->getVertices(); 131 | $vertices = []; 132 | foreach($verticesVectors as $vector) { 133 | $vertices[] = $vector->x; 134 | $vertices[] = $vector->y; 135 | $vertices[] = $vector->z; 136 | } 137 | $indices = $obj->getVertexFaces(); 138 | $indices = array_map(function($index) { return $index - 1; }, $indices); 139 | 140 | $normalObjects = $obj->getVertexNormals(); 141 | $normals = []; 142 | foreach($normalObjects as $index => $normalObject) { 143 | if(!($normalObject instanceof Vector)) { 144 | echo "INDEX: $index\n"; 145 | var_dump($normalObject); 146 | die; 147 | } 148 | else { 149 | $normals[] = $normalObject->x; 150 | $normals[] = $normalObject->y; 151 | $normals[] = $normalObject->z; 152 | } 153 | } 154 | 155 | // First, set the container's VAO (and VBO) 156 | glGenVertexArrays(1, $containerVAOS); $containerVAO = $containerVAOS[0]; 157 | glBindVertexArray($containerVAO); 158 | 159 | glGenBuffers(1, $VBOS); $VBO = $VBOS[0]; 160 | 161 | glBindBuffer(GL_ARRAY_BUFFER, $VBO); 162 | glBufferData(GL_ARRAY_BUFFER, sizeof($vertices) * 4, $vertices, GL_STATIC_DRAW); 163 | 164 | glGenBuffers(1, $vbo_normals); $vbo_normal = $vbo_normals[0]; 165 | glBindBuffer(GL_ARRAY_BUFFER, $vbo_normal); 166 | glBufferData(GL_ARRAY_BUFFER, count($normals) * 4, $normals, GL_STATIC_DRAW); 167 | 168 | 169 | glGenBuffers(1, $ebos); $ebo = $ebos[0]; 170 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, $ebo); 171 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, count($indices) * 4, $indices, GL_STATIC_DRAW); 172 | 173 | // Position attribute 174 | glEnableVertexAttribArray(0); 175 | glBindBuffer(GL_ARRAY_BUFFER, $VBO); 176 | glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 177 | // Normal attribute 178 | glEnableVertexAttribArray(1); 179 | glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0); 180 | glBindVertexArray(0); 181 | 182 | // Then, we set the light's VAO (VBO stays the same. After all, the vertices are the same for the light object (also a 3D cube)) 183 | glGenVertexArrays(1, $lightVAOS); $lightVAO = $lightVAOS[0]; 184 | glBindVertexArray($lightVAO); 185 | 186 | glGenBuffers(1, $VBOS_light); $VBO_light = $VBOS_light[0]; 187 | 188 | glBindBuffer(GL_ARRAY_BUFFER, $VBO_light); 189 | glBufferData(GL_ARRAY_BUFFER, sizeof($lightvertices) * 4, $lightvertices, GL_STATIC_DRAW); 190 | 191 | // Set the vertex attributes (only position data for the lamp)) 192 | glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * 4, 0); // Note that we skip over the normal vectors 193 | glEnableVertexAttribArray(0); 194 | glBindVertexArray(0); 195 | 196 | $event = new SDL_Event; 197 | while(true) { 198 | // Calculate deltatime of current frame 199 | $lightingShader = &$GLOBALS['lightingShader']; 200 | $lampShader = &$GLOBALS['lampShader']; 201 | $lastFrame = &$GLOBALS['lastFrame']; 202 | $deltaTime = &$GLOBALS['deltaTime']; 203 | $currentFrame = microtime(true); 204 | $deltaTime = $currentFrame - $lastFrame; 205 | $lastFrame = $currentFrame; 206 | 207 | // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions 208 | do_movement(); 209 | 210 | // Clear the colorbuffer 211 | glClearColor(0.1, 0.1, 0.1, 1.0); 212 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 213 | 214 | // Use cooresponding shader when setting uniforms/drawing objects 215 | $lightingShader->use(); 216 | $objectColorLoc = glGetUniformLocation($lightingShader->getId(), "objectColor"); 217 | glUniform3f($objectColorLoc, 1.0, .5, 0.31); 218 | $lightColorLoc = glGetUniformLocation($lightingShader->getId(), "lightColor"); 219 | glUniform3f($lightColorLoc, 1.0, 1.0, 1.0); 220 | $lightPosLoc = glGetUniformLocation($lightingShader->getId(), "lightPos"); 221 | glUniform3f($lightPosLoc, $lightPos->x, $lightPos->y, $lightPos->z); 222 | $viewPosLoc = glGetUniformLocation($lightingShader->getId(), "viewPos"); 223 | glUniform3f($viewPosLoc, $camera->position->x, $camera->position->y, $camera->position->z); 224 | 225 | // Create camera transformations 226 | $view = new Matrix(); 227 | $view = $camera->GetViewMatrix(); 228 | $projection = Transform::perspective($camera->zoom, floatval(WIDTH / HEIGHT), 0.1, 100.0); 229 | // Get the uniform locations 230 | $modelLoc = glGetUniformLocation($lightingShader->getId(), "model"); 231 | $viewLoc = glGetUniformLocation($lightingShader->getId(), "view"); 232 | $projLoc = glGetUniformLocation($lightingShader->getId(), "projection"); 233 | // Pass the matrices to the shader 234 | glUniformMatrix4fv($viewLoc, 1, GL_FALSE, $view->toRowVector()); 235 | glUniformMatrix4fv($projLoc, 1, GL_FALSE, $projection->toRowVector()); 236 | 237 | // Draw the container (using container's vertex attributes) 238 | glBindVertexArray($containerVAO); 239 | $model = new Matrix; 240 | $model = $model->scale(0.3); 241 | $model = Transform::rotate($model, deg2rad(90), new Vector(1, 1, 1)); 242 | glUniformMatrix4fv($modelLoc, 1, GL_FALSE, $model->toRowVector()); 243 | $a = count($indices); 244 | glDrawElements(GL_TRIANGLES, $a, GL_UNSIGNED_INT, null); 245 | glBindVertexArray(0); 246 | 247 | // Also draw the lamp object, again binding the appropriate shader 248 | $lampShader->use(); 249 | // Get location objects for the matrices on the lamp shader (these could be different on a different shader) 250 | $modelLoc = glGetUniformLocation($lampShader->getId(), "model"); 251 | $viewLoc = glGetUniformLocation($lampShader->getId(), "view"); 252 | $projLoc = glGetUniformLocation($lampShader->getId(), "projection"); 253 | // Set matrices 254 | glUniformMatrix4fv($viewLoc, 1, GL_FALSE, $view->toRowVector()); 255 | glUniformMatrix4fv($projLoc, 1, GL_FALSE, $projection->toRowVector()); 256 | $model = new Matrix; 257 | $model = Transform::translate($model, $lightPos); 258 | $model = $model->scale(0.2); // Make it a smaller cube 259 | glUniformMatrix4fv($modelLoc, 1, GL_FALSE, $model->toRowVector()); 260 | // Draw the light object (using light's vertex attributes) 261 | glBindVertexArray($lightVAO); 262 | glDrawArrays(GL_TRIANGLES, 0, 36); 263 | glBindVertexArray(0); 264 | 265 | // Swap the screen buffers 266 | SDL_GL_SwapWindow($window); 267 | while(SDL_PollEvent($event)) { 268 | switch($event->type) { 269 | case SDL_MOUSEMOTION: 270 | $mouse_callback($event->motion->x, $event->motion->y); 271 | break; 272 | case SDL_KEYDOWN: 273 | $symChar = chr($event->key->keysym->sym); 274 | $keys['w'] = $symChar == 'w'; 275 | $keys['s'] = $symChar == 's'; 276 | $keys['a'] = $symChar == 'a'; 277 | $keys['d'] = $symChar == 'd'; 278 | break; 279 | case SDL_KEYUP: 280 | $keys = array_fill_keys(range('a', 'z'), false); 281 | break; 282 | } 283 | } 284 | 285 | } 286 | 287 | function do_movement() 288 | { 289 | global $deltaTime; 290 | $camera = &$GLOBALS['camera']; 291 | $keys = &$GLOBALS['keys']; 292 | // Camera controls 293 | if ($keys['w']) { 294 | $camera->ProcessKeyboard(Camera::FORWARD, $deltaTime); 295 | } 296 | if ($keys['s']) { 297 | $camera->ProcessKeyboard(Camera::BACKWARD, $deltaTime); 298 | } 299 | if ($keys['a']) { 300 | $camera->ProcessKeyboard(Camera::LEFT, $deltaTime); 301 | } 302 | if ($keys['d']) { 303 | $camera->ProcessKeyboard(Camera::RIGHT, $deltaTime); 304 | } 305 | } 306 | 307 | 308 | -------------------------------------------------------------------------------- /examples/models/cube.obj: -------------------------------------------------------------------------------- 1 | # cube.obj 2 | # 3 | 4 | o cube 5 | mtllib cube.mtl 6 | 7 | v -0.500000 -0.500000 0.500000 8 | v 0.500000 -0.500000 0.500000 9 | v -0.500000 0.500000 0.500000 10 | v 0.500000 0.500000 0.500000 11 | v -0.500000 0.500000 -0.500000 12 | v 0.500000 0.500000 -0.500000 13 | v -0.500000 -0.500000 -0.500000 14 | v 0.500000 -0.500000 -0.500000 15 | 16 | vt 0.000000 0.000000 17 | vt 1.000000 0.000000 18 | vt 0.000000 1.000000 19 | vt 1.000000 1.000000 20 | 21 | vn 0.000000 0.000000 1.000000 22 | vn 0.000000 1.000000 0.000000 23 | vn 0.000000 0.000000 -1.000000 24 | vn 0.000000 -1.000000 0.000000 25 | vn 1.000000 0.000000 0.000000 26 | vn -1.000000 0.000000 0.000000 27 | 28 | g cube 29 | usemtl cube 30 | s 1 31 | f 1/1/1 2/2/1 3/3/1 32 | f 3/3/1 2/2/1 4/4/1 33 | s 2 34 | f 3/1/2 4/2/2 5/3/2 35 | f 5/3/2 4/2/2 6/4/2 36 | s 3 37 | f 5/4/3 6/3/3 7/2/3 38 | f 7/2/3 6/3/3 8/1/3 39 | s 4 40 | f 7/1/4 8/2/4 1/3/4 41 | f 1/3/4 8/2/4 2/4/4 42 | s 5 43 | f 2/1/5 8/2/5 4/3/5 44 | f 4/3/5 8/2/5 6/4/5 45 | s 6 46 | f 7/1/6 1/2/6 5/3/6 47 | f 5/3/6 1/2/6 3/4/6 48 | 49 | -------------------------------------------------------------------------------- /examples/models/gourd.obj: -------------------------------------------------------------------------------- 1 | v -0.23876920554499864 1.3103797270601687 0.13001260700009193 2 | v -0.27582915374543276 1.2582563331865875 0.12364597630502337 3 | v -0.2674888336016338 1.3474373225751202 0.15912747459742976 4 | v -0.3128662756980407 1.222713216834852 0.14623565543301947 5 | v -0.3018967864385568 1.3832552573955716 0.1992584345763206 6 | v -0.3291084911674431 1.4015778151496097 0.23515159787549716 7 | v -0.3393653203892503 1.1606446817887044 0.25033862660881895 8 | v -0.32933702685159627 1.3872894114706185 0.30297184764306634 9 | v -0.34413945029647036 1.1847846590886826 0.3161902839586921 10 | v -0.32731404147036136 1.3472171185436952 0.33599708012099205 11 | v -0.31993727304296354 1.2010232341929186 0.3533614819463716 12 | v -0.30726711945847285 1.2956437760677335 0.3643485926629952 13 | v -0.2877856463729185 1.2493470906219926 0.38230872912669633 14 | v -0.21034318989786122 1.3531672444828033 0.1537169917653439 15 | v -0.21145627080982005 1.3818523867813413 0.35175494063536605 16 | v -0.2338628137428242 1.3442372246769223 0.37948021085512573 17 | v -0.25614030179208813 1.2952633550210815 0.3911502328871025 18 | v -0.596105380500693 -0.6768462432797441 -0.9120215121805894 19 | v -0.10001338605742703 -0.9910441617396678 -0.7028175040329147 20 | v -0.16086384627984987 -1.127277664194341 -0.7434844726798386 21 | v -0.008083895898474806 -1.0921252683249256 -0.5243409146431066 22 | v -0.07976516143635025 -1.276866970105867 -0.5252506365091272 23 | v -0.020060506382965703 -1.2334385749192633 -0.301325040448603 24 | v -0.07990779791476262 -1.3509036976740292 -0.341070036161337 25 | v -0.10169053410627815 -1.2068870189299477 -0.04876722079973187 26 | v -0.1519817903091755 -1.365510665871866 -0.15692439889429793 27 | v -0.2601279041091756 -1.1885795093023326 0.10988970110975217 28 | v -0.31729579292888604 -1.321268264156361 0.059441628673455316 29 | v -0.848568870055825 -0.9383248633714683 0.23982837834317694 30 | v -0.2841115740583825 -1.2078773490579697 -0.8036506322954367 31 | v -0.22231836409372388 -1.3705711792653117 -0.6258835168322516 32 | v -0.19808583052036852 -1.4522159317791117 -0.3886956275749503 33 | v -0.31271194883273773 -1.4812229673897357 -0.1662599441498861 34 | v -0.4468655428183257 -1.4081208865117936 0.030309816870830293 35 | v -0.3988207279452833 -0.9783603900495396 -0.8833077012801736 36 | v -0.4261847167822431 -1.2538563022802836 -0.832657802483938 37 | v -0.38091428944031497 -1.4323612424714172 -0.6713096485927353 38 | v -0.34392672880812863 -1.5296402016703727 -0.4359666117195356 39 | v -0.47121275738702567 -1.5427481346322585 -0.212699971365956 40 | v -0.5840335467653923 -1.4499471972736035 -0.01688965681846319 41 | v -0.5965324664537639 -1.2310376567603918 0.15439728723762638 42 | v -0.603970626930515 -0.9730496272867387 -0.9442929048887062 43 | v -0.6584407430024051 -1.2331761333320834 -0.8746205623410716 44 | v -0.709409821847784 -1.4659429722203778 -0.7154020228441985 45 | v -0.6644813362834862 -1.5771682475681057 -0.51042113309235 46 | v -0.7894059105187994 -1.5638233094298595 -0.3088200440614581 47 | v -0.8162833445262949 -1.4310813233699453 -0.05752847701987319 48 | v -0.8117676576018125 -1.234439602574674 0.13414076435148883 49 | v -0.25834762010828993 -0.6951673252373165 -0.7923673206368221 50 | v -0.06248973045542924 -0.7665910821077954 -0.6540399700991502 51 | v 0.07611239708492351 -0.9156476836861951 -0.20536770047473785 52 | v -0.031081271477573048 -0.8994758181564453 0.04312489218518984 53 | v -0.2509457867081838 -0.9602191023294494 0.1949888000417654 54 | v -0.5314775775236663 -0.9170871483914047 0.27604867586122167 55 | v -0.698201286366758 -0.8975001213210745 -0.9599982435061234 56 | v -0.8293665978692493 -1.11509528462743 -0.9146490325020323 57 | v -0.9619048200796854 -1.343162090335404 -0.7880316555337348 58 | v -1.0472124286277014 -1.4730438773829664 -0.5605464015223269 59 | v -1.060765551847539 -1.4641134058825243 -0.2855663528073091 60 | v -1.0004246660561544 -1.3283874042894974 -0.03361413042981279 61 | v -0.9104906458141931 -1.1662066485845088 0.1470252534214227 62 | v -0.9586855869711515 -0.6710831333901544 -0.9367557030770179 63 | v -1.2445793305522892 -0.817542042890274 -0.8973407152418248 64 | v -1.2659871743768685 -0.6801247466768301 -0.8490486738261083 65 | v -1.4417357951365137 -0.892844113645334 -0.7517043712681761 66 | v -1.476802737695221 -0.7360019859679737 -0.6685856347091148 67 | v -1.5639841715332439 -0.9191614582919794 -0.5287575689432107 68 | v -1.5681656901876435 -0.7927271011174322 -0.4991311239237613 69 | v -1.5326259636093063 -1.0039824068887115 -0.28969248502613 70 | v -1.5489494701267934 -0.8242411750516833 -0.3018251138498018 71 | v -1.407890071989428 -1.018040171212245 -0.06605615148067337 72 | v -1.4223317944946532 -0.8723090313725681 -0.05316658252587531 73 | v -1.1652203387672957 -0.9337169196632413 0.1334184078263284 74 | v -1.1255438855619244 -0.45287889159761474 -0.7915489789158711 75 | v -1.3279205175383988 -0.42378587112767446 -0.6057450114372587 76 | v -1.453237253290355 -0.5055549645946847 -0.40734951169873873 77 | v -1.4148957872068073 -0.5304237767693063 -0.16308494761654216 78 | v -1.289436358384456 -0.6584542134820716 0.049305709577394455 79 | v -0.8874951265560681 -0.8248028576559522 -0.9565338521560323 80 | v -1.1657720297488638 -0.9232322177159897 -0.9113461515493453 81 | v -1.3737606650637482 -1.05988953884744 -0.7658589961519274 82 | v -1.5010039128600727 -1.0931510893936602 -0.5582767873636508 83 | v -1.4601034487302784 -1.1654443984569987 -0.3270400944072667 84 | v -1.3300721765655639 -1.126145329626444 -0.07288783559541256 85 | v -1.094027683771837 -1.084366608811451 0.10682087754556222 86 | v -1.0875937948798378 -1.0722876078076398 -0.8950930575225976 87 | v -1.2487802398372811 -1.199621201720314 -0.770810356893762 88 | v -1.3871797127872325 -1.2453352818416719 -0.5725538075637561 89 | v -1.3336683013633743 -1.303381182432141 -0.33953009810380114 90 | v -1.2386603306792545 -1.2586899629846382 -0.12341526133552151 91 | v -0.847389582770811 -0.478492980249323 -0.871016832402294 92 | v -1.0629050406633582 -0.33601400374427853 -0.7258100434517166 93 | v -1.2190735055805353 -0.29624060404360103 -0.5635619964306117 94 | v -1.3517105212108151 -0.3476974272688013 -0.3492936473235696 95 | v -1.3091051787212946 -0.40781276676789235 -0.10339425594585269 96 | v -1.2168089660357586 -0.5274920225978963 0.06741335477163105 97 | v -1.0511503152740245 -0.7416804143259951 0.2049141271815988 98 | v -0.6820493320101108 -0.4073454070130155 -0.8362462682349809 99 | v -0.8480346738093036 -0.22394454471293013 -0.6859356370420204 100 | v -0.9382037144425833 -0.08920601913082365 -0.4560668167387506 101 | v -1.0896315173661946 -0.13537742027486113 -0.24763788309746104 102 | v -1.0177578267683933 -0.19112387317463178 7.070529650376467E-4 103 | v -1.0348062333853838 -0.41038161623017794 0.1399093358829532 104 | v -0.9396488481908281 -0.6321302849485207 0.24387425328076773 105 | v -0.09560436290090499 1.339214093370152 0.1477579579447047 106 | v -0.15273510877349308 1.2957419873888067 0.10995645328754174 107 | v -0.062050527956707575 1.3692309912304754 0.1955267069140381 108 | v -1.521773942288455E-4 1.3554620235219368 0.3227203242573578 109 | v -0.10349110756088271 1.3137976974225336 0.4178816230110331 110 | v -0.15085642703030017 1.2694959538207045 0.43225990586812474 111 | v -0.21433174824491863 1.2202115319934645 0.42359844208844455 112 | v -0.21917009134413754 1.249857125588988 0.0995416059368744 113 | v -0.28246419070242684 1.2050401515702542 0.11644643644430475 114 | v -0.3129756717999029 1.163166153030332 0.14503962345021287 115 | v -0.32664932338661334 1.1471685974256742 0.3296679490818033 116 | v -0.2751151389208091 1.178548147296377 0.38859847543695397 117 | v -0.07117824697642426 1.2833923335104869 0.10155506218543657 118 | v 0.01952628579214415 1.2268383174511577 0.08762970595474523 119 | v -0.0533728492267706 1.1780899339795514 0.041486476961526436 120 | v -0.12159853328026078 1.2160393526967515 0.06191305596390384 121 | v -0.03216112253813483 1.3372853305457484 0.16511543805230214 122 | v 0.0731556655610805 1.26540329490592 0.1618196085705 123 | v -0.018012120440415495 1.3646669050570877 0.22983374254345476 124 | v 0.10367094281488036 1.2843407275170273 0.25238198525389427 125 | v 0.13140177353855467 1.2478160316648583 0.32763802931035096 126 | v -0.056021811076326464 1.3299507664867958 0.39305267822379214 127 | v 0.07522175402077194 1.2507143399891454 0.3956619662984644 128 | v -0.08281234911568472 1.2703421796138938 0.4402240123229857 129 | v 0.01795293748424096 1.1977292385399962 0.4495759996401428 130 | v -0.140084567072329 1.1981313068931814 0.4549247925876616 131 | v -0.055730483438343095 1.134204503245634 0.4743453892047482 132 | v -0.195843423418774 1.1250804448063756 0.4395501060994016 133 | v -0.13648241697035543 1.0762988502857962 0.4642071929538253 134 | v -0.1320833582585817 1.118879626710536 0.03027101424435127 135 | v -0.17789451123739403 1.1419876741742214 0.052250123394135074 136 | v -0.20244412759751665 1.062628011979282 0.0508408807532532 137 | v -0.23210941728461448 1.0796495973528117 0.07190570714367979 138 | v -0.26030340316362355 1.0179148935053772 0.10527188614157675 139 | v -0.29525684897940946 0.9675080117623716 0.1792173306975986 140 | v -0.28826541284389207 0.9677050604055095 0.2798794723956473 141 | v -0.2632513574265279 0.9931303693008816 0.3514136070432927 142 | v -0.28646037093541493 1.0185581755171358 0.3282172719023405 143 | v -0.2086964110925687 1.0259454248881235 0.4189416705014296 144 | v -0.2467883757867712 1.0595447508107605 0.3933816015630798 145 | v 0.17872313693801953 1.025246834722123 0.04349401870518004 146 | v 0.06748632295477272 1.0328368970330073 -0.0012005056093327012 147 | v 0.2561423061057405 1.0136281055295011 0.10835507124081907 148 | v 0.300950261734067 0.9431608110206416 0.28643187767591677 149 | v 0.18936841832020435 0.9319869673270735 0.44817741477373196 150 | v 0.09325438236168647 0.9204810011470623 0.4786885904815903 151 | v -0.026875929876898914 0.9171992918687374 0.4788032161574475 152 | v -0.050991484084989845 1.030898509265369 -0.008079474184983611 153 | v -0.16209114356370188 1.0159498925407309 0.024676756222088137 154 | v -0.229159459612385 0.9354422138631637 0.36859933084343927 155 | v -0.1391731970008425 0.9234519262530181 0.44119603386135564 156 | v 0.17861510065239114 0.9029942588889944 -0.005193118717157615 157 | v 0.20885071989207965 0.5755957905566027 -0.07667087792795438 158 | v 0.07966628487324764 0.8444141445957631 -0.05571698567292751 159 | v 0.10836530729913466 0.5997704001367645 -0.10999773301638337 160 | v 0.267798986856911 0.9395661466021183 0.07867890346497927 161 | v 0.2937291293341934 0.962459454773473 0.17552656684668122 162 | v 0.3397881281649465 0.4568368997780585 0.1767550046536417 163 | v 0.25272039926472245 0.9123418286838364 0.3839045766826548 164 | v 0.1960131812497361 0.8515960540706153 0.4438518114132365 165 | v 0.08617665401052353 0.7897714182096348 0.4648540365288201 166 | v 0.11695626676834338 0.46301165363215435 0.39082411170929 167 | v -0.018812474436488397 0.7237549378258146 0.44527487016595946 168 | v 0.009515024453930019 0.47867577559453145 0.3928715296525722 169 | v -0.012905137512460198 0.6217365064396034 -0.10774026933953917 170 | v -0.020542415672755155 0.7766143499424125 -0.07025333721081264 171 | v -0.11420333688264363 0.6301372081172665 -0.072320114787061 172 | v -0.12027343756275882 0.7162053532704167 -0.04479408000218762 173 | v -0.19469603733957327 0.6638012353563264 0.0019509816624666348 174 | v -0.24865269735816442 0.5979937949414752 0.09451062907589113 175 | v -0.23773508294912143 0.6112776440191625 0.21892825264540403 176 | v -0.18634370550533172 0.5413926271476547 0.2949493622643064 177 | v -0.1895051304036615 0.6312093666452024 0.3081881168248471 178 | v -0.10427297470446559 0.5097569398714669 0.35705778790619097 179 | v -0.11098916529176285 0.6655311694160618 0.39159830628358067 180 | v 0.1876342069811111 0.5033061437989215 -0.10483268880194742 181 | v 0.09809358624263935 0.17576055344835947 -0.22660111284413842 182 | v 9.980600042878598E-4 0.2776940657404102 -0.23833721224985494 183 | v 0.06202604473373216 0.5143367290533036 -0.14430238389579206 184 | v 0.2601771625596767 0.5132495618693441 -0.0419826119632792 185 | v 0.2267034323045877 -0.07934967297543495 0.02556359016082569 186 | v 0.18248639872254088 0.4180673661872462 0.35325990274594876 187 | v 0.09338059505857496 0.38783248945634874 0.3746744992397327 188 | v -0.005211606777756715 0.04917999260227923 0.2990491470058861 189 | v -0.03849106672839849 0.39120902770935095 0.367016939925659 190 | v -0.10848056289935136 0.1435512953626317 0.31865722665290575 191 | v -0.0932417226328324 0.3598705333665368 -0.2074025730478351 192 | v -0.06719701000163651 0.5066450508624447 -0.1397429150410627 193 | v -0.1804473794799147 0.41746664230742225 -0.1415871127280521 194 | v -0.16404691441086264 0.5008696549815044 -0.09943713866384862 195 | v -0.24991610243976733 0.46142536820852903 -0.04084433768174924 196 | v -0.28761411639861034 0.44737779602280475 0.051054453447751835 197 | v -0.28675863948263974 0.416295470137208 0.14635962931629456 198 | v -0.254500590852495 0.32669003381612766 0.23531552878884276 199 | v -0.231372001824006 0.41834268077179726 0.24280756749780402 200 | v -0.19207899925896893 0.23874733244600602 0.29550374929060313 201 | v -0.15628752178315608 0.3974920744082751 0.31353339526127444 202 | v -0.018720751877417497 0.062427271517513046 -0.3423575873860938 203 | v -0.05158961781091372 -0.2563933968214236 -0.49800580550559054 204 | v -0.20088495830404476 -0.13126411196599852 -0.5453441726394352 205 | v -0.18340769457458989 0.09825169285259472 -0.3943097123183823 206 | v 0.12115365957039037 0.014420223788874923 -0.24037782041932212 207 | v 0.056559451013174264 -0.36062459822625886 -0.40692266576968744 208 | v 0.12212578753997294 -0.6050598321387264 -0.12437295900412774 209 | v 0.025258295975196174 -0.10322945063945176 0.24768994532951785 210 | v -0.06640266552744624 -0.5010310085837314 0.19723160290838115 211 | v -0.145384934862913 -0.09303562620026448 0.3026990669448157 212 | v -0.2080530513736607 -0.4402766255051616 0.27854398626511434 213 | v -0.3201688747286834 -0.069472750700044 0.3021999728028007 214 | v -0.3764229875624985 -0.3372841738879878 0.3196175137825808 215 | v -0.37103840912195013 -0.018343714126245417 -0.5181695682676257 216 | v -0.3624876398424141 0.11792333476126983 -0.3885156944272048 217 | v -0.5369907859125455 0.05987335312325521 -0.420070558870981 218 | v -0.49722492713673616 0.13410703737954682 -0.3286188877172944 219 | v -0.6294317441594179 0.11556113739693963 -0.26391312063853545 220 | v -0.74173498336992 0.08053780182128528 -0.12522747001774567 221 | v -0.6901485280221654 0.042138462724677694 0.04298647182897286 222 | v -0.6583061345706847 -0.08271666421665431 0.17909368084528765 223 | v -0.5930778951386746 0.01940614282887867 0.15083850228675535 224 | v -0.5336280893809849 -0.20845754472929892 0.2850729045500069 225 | v -0.4863419744110133 -0.033084460741767234 0.24177778209818324 226 | v -0.16421418750489497 -0.3009066302678531 -0.613469962903272 227 | v -0.19121648139938338 -0.49736348828867183 -0.7024015487555098 228 | v -0.3804429066794447 -0.3517580490090136 -0.7461890303461363 229 | v -0.36911610223035285 -0.19924428750907905 -0.6606716953472738 230 | v 0.00764144937164241 -0.41591976904898176 -0.48949143091766145 231 | v -0.00703132676232705 -0.639152352439578 -0.5705632382430396 232 | v 0.11082364953963271 -0.46984782407830805 -0.3169906454178008 233 | v 0.07681783005303255 -0.7589168860036708 -0.4146953894835867 234 | v 0.023932473668473467 -0.5670301759646578 0.09632170271937375 235 | v -0.139698107729481 -0.5845442431079642 0.224328828951515 236 | v -0.12909344686888494 -0.82452130403786 0.17197986976368612 237 | v -0.35629678802794823 -0.5164555824199508 0.3146739763415395 238 | v -0.3207143923909673 -0.7555247084101276 0.27546974969494803 239 | v -0.5751666842740498 -0.42980212239695187 0.3247894461401142 240 | v -0.5608819388605969 -0.6300128226097699 0.3256888806317336 241 | v -0.6119993988065029 -0.2039436789589 -0.7058985888062624 242 | v -0.5690995198999165 -0.12062867425850417 -0.6367858256444157 243 | v -0.7745480379862542 -0.08299685419757988 -0.5533065828441973 244 | v -0.9059965161698623 -0.27579432003345206 0.1565710587409764 245 | v -0.7733491979650087 -0.48524750438686576 0.2900036375382926 246 | v -0.7448096323038795 -0.3254807309936029 0.26563969024312495 247 | v -0.1292811121767781 0.24541226127424362 -0.27813642684707096 248 | v -0.012722182411993922 0.17872354694047157 -0.2856442543998048 249 | v -0.2428141364892664 0.29395739556129535 -0.22349063319337525 250 | v -0.3411247577494312 0.31901208295467953 -0.12724776419557868 251 | v -0.3992091957752286 0.31073037338569687 -0.0036776738917693227 252 | v -0.39029961638808786 0.25895363915674446 0.12264318016053902 253 | v -0.3311242920511251 0.18560722865550605 0.22621753264795585 254 | v -0.24091339429176825 0.1083564943253534 0.2905482642422535 255 | v -0.12951005521262673 0.03536832888417705 0.30925230551932015 256 | v 0.09116388438362256 0.10905454185092361 -0.24903014897171805 257 | v 0.16893286792711723 0.09534659783694158 -0.17487528542655814 258 | v 0.08621995597156243 -0.006153152546389401 0.24651124997927 259 | v -0.013839682800429801 -0.01976756022956282 0.2857709647911246 260 | v -0.14224466965791016 1.3831523327333446 0.30144101500423315 261 | v -0.13605604833821014 1.393857595270661 0.2766140427570333 262 | v -0.13002715466520928 1.3934280277792825 0.2520685743777088 263 | v -0.12423922657418207 1.388769918728889 0.23066988277566788 264 | v -0.19518443866089988 1.3928509577654855 0.20378772481501994 265 | v -0.24148774025737788 1.3945399882729024 0.23016096348757714 266 | v -0.25791021093344335 1.4037411161856639 0.24787129664381718 267 | v -0.2620654518979459 1.3957442061286076 0.284527879789462 268 | v -0.20139872286954744 1.389485467634939 0.32349211851139514 269 | v -0.1488091510125688 1.3781207203872883 0.3200274224926117 270 | v -0.13158193764344558 1.4250679750579258 0.2807314628260412 271 | v -0.11595643515633988 1.4245682404098425 0.22163997660384924 272 | v -0.20627424326148192 1.4124911965266467 0.18741680061016427 273 | v -0.26445442393150115 1.400769211913228 0.22122294388061534 274 | v -0.2872685557740087 1.406883382542881 0.2444293361608223 275 | v -0.2899360821624794 1.3935839799698049 0.29084828102857163 276 | v -0.21178559249014803 1.3994915112001476 0.34039022323541024 277 | v -0.1429001429580068 1.3993976870289333 0.3353182110462305 278 | v -0.2857648326576529 1.5187468359348737 0.3082338172397895 279 | v -0.27727616014547757 1.530338168645061 0.2625549569640586 280 | v -0.3334604957630521 1.4880341091190048 0.23308840213734724 281 | v -0.36604087340725666 1.453055527215242 0.25713264595649266 282 | v -0.3828999421792846 1.4454714177478138 0.2753297576919234 283 | v -0.37751818239371726 1.4313472154601539 0.31006947817311087 284 | v -0.32631523474701046 1.4631317857783432 0.35061576401157374 285 | v -0.2807143588260308 1.4921408310497963 0.34796225284311 286 | v -0.359718447897886 1.5667423492396997 0.3249332982344497 287 | v -0.35604269069748223 1.5843518466712045 0.27844553809784006 288 | v -0.3980451782163092 1.5262919573931168 0.24430381106553892 289 | v -0.4181656377402749 1.4792909565111614 0.2664080870596363 290 | v -0.43194785784379036 1.4648905070555227 0.2846242013341748 291 | v -0.42130540631457 1.4501970581589543 0.31964088446057193 292 | v -0.3805277869148768 1.4954324349453687 0.3644531272029499 293 | v -0.34517821394105 1.5392865146237846 0.36417365388479916 294 | v -0.525253166509216 1.5797756350730938 0.3618339573500447 295 | v -0.5427781715907363 1.600035553232815 0.32113583567835097 296 | v -0.5227646170883478 1.5418236240694803 0.27390553690397157 297 | v -0.4933105257778895 1.4972331194307962 0.2843137977922944 298 | v -0.48710328833367594 1.4754098821989285 0.2977991260001166 299 | v -0.46547571828721857 1.4702527709605107 0.3292892793473014 300 | v -0.474604834039762 1.518936744884534 0.3841417968234773 301 | v -0.4907531253963674 1.570392934863122 0.3952265040148293 302 | v -0.6190130970388793 1.5696558595459142 0.38003232814495125 303 | v -0.6355019539055907 1.585899126949611 0.3462181836390502 304 | v -0.6139504237029327 1.5398059391590697 0.3053658122107581 305 | v -0.5784210799208646 1.4868135510777596 0.32414429004118506 306 | v -0.5598034658588011 1.483728452273698 0.350505735413888 307 | v -0.5714200313571158 1.5226275895992984 0.3975745784787094 308 | v -0.5892615137516267 1.5640904735931778 0.40790221218885614 309 | v -0.7207897200255293 1.5567789987446936 0.40116346301661054 310 | v -0.7290467383099924 1.5726640148199242 0.3702920060376821 311 | v -0.7270750137803762 1.525483825821082 0.33867446181335653 312 | v -0.71560668386606 1.4727027815509461 0.3595899705139178 313 | v -0.7013827394050692 1.4661328607881354 0.38307846161479897 314 | v -0.6976434083183529 1.504754391368148 0.4208247199303316 315 | v -0.6983812574358621 1.5446905536547915 0.42637673695906997 316 | v -0.9070526524958897 1.4960808856355494 0.4172580276830761 317 | v -0.8863039803791803 1.474513559264521 0.3901551190206042 318 | v -0.8554404727488869 1.4489886081267185 0.39960983011290785 319 | v -0.8436098200111913 1.4494922096871927 0.415802278250204 320 | v -0.875124048994981 1.4891447909953186 0.4545401079578815 321 | v -0.9884730850864034 1.4369108601544263 0.4354713488045925 322 | v -1.0097509656761623 1.402303016901423 0.41539549299271056 323 | v -1.0261663143967716 1.3653907886614334 0.43778258638601936 324 | v -1.0193881127383304 1.3571557442500386 0.4576102108491951 325 | v -0.9801045292318034 1.4108781558731749 0.4839256718868889 326 | v -1.0646015617123321 1.3754696203441494 0.4676547749135673 327 | f 1 2 3 328 | f 4 5 3 329 | f 4 3 2 330 | f 9 10 7 331 | f 10 8 7 332 | f 11 12 9 333 | f 12 10 9 334 | f 12 11 13 335 | f 1 3 14 336 | f 10 16 15 337 | f 10 15 8 338 | f 12 17 16 339 | f 12 16 10 340 | f 17 12 13 341 | f 21 22 20 342 | f 21 20 19 343 | f 23 24 22 344 | f 23 22 21 345 | f 25 26 23 346 | f 26 24 23 347 | f 27 28 25 348 | f 28 26 25 349 | f 22 31 20 350 | f 31 30 20 351 | f 24 32 22 352 | f 32 31 22 353 | f 26 33 32 354 | f 26 32 24 355 | f 28 34 33 356 | f 28 33 26 357 | f 31 37 30 358 | f 37 36 30 359 | f 32 38 31 360 | f 38 37 31 361 | f 33 39 38 362 | f 33 38 32 363 | f 34 40 39 364 | f 34 39 33 365 | f 18 35 42 366 | f 36 43 35 367 | f 43 42 35 368 | f 37 44 36 369 | f 44 43 36 370 | f 38 45 37 371 | f 45 44 37 372 | f 39 46 45 373 | f 39 45 38 374 | f 40 47 46 375 | f 40 46 39 376 | f 41 48 47 377 | f 41 47 40 378 | f 48 41 29 379 | f 51 23 21 380 | f 52 25 51 381 | f 25 23 51 382 | f 53 27 52 383 | f 27 25 52 384 | f 18 42 55 385 | f 43 56 42 386 | f 56 55 42 387 | f 44 57 43 388 | f 57 56 43 389 | f 45 58 44 390 | f 58 57 44 391 | f 46 59 58 392 | f 46 58 45 393 | f 47 60 59 394 | f 47 59 46 395 | f 48 61 60 396 | f 48 60 47 397 | f 61 48 29 398 | f 63 64 62 399 | f 65 66 64 400 | f 65 64 63 401 | f 67 68 66 402 | f 67 66 65 403 | f 69 70 67 404 | f 70 68 67 405 | f 71 72 69 406 | f 72 70 69 407 | f 73 72 71 408 | f 64 74 62 409 | f 66 75 64 410 | f 75 74 64 411 | f 68 76 66 412 | f 76 75 66 413 | f 70 77 76 414 | f 70 76 68 415 | f 72 78 77 416 | f 72 77 70 417 | f 73 78 72 418 | f 81 65 63 419 | f 81 63 80 420 | f 82 67 65 421 | f 82 65 81 422 | f 83 69 82 423 | f 69 67 82 424 | f 84 71 83 425 | f 71 69 83 426 | f 86 80 79 427 | f 87 81 80 428 | f 87 80 86 429 | f 88 82 81 430 | f 88 81 87 431 | f 89 83 88 432 | f 83 82 88 433 | f 90 84 89 434 | f 84 83 89 435 | f 85 84 90 436 | f 57 87 86 437 | f 57 86 56 438 | f 58 88 87 439 | f 58 87 57 440 | f 59 89 58 441 | f 89 88 58 442 | f 60 90 59 443 | f 90 89 59 444 | f 75 93 74 445 | f 93 92 74 446 | f 76 94 75 447 | f 94 93 75 448 | f 77 95 94 449 | f 77 94 76 450 | f 78 96 95 451 | f 78 95 77 452 | f 18 91 98 453 | f 92 99 91 454 | f 99 98 91 455 | f 93 100 92 456 | f 100 99 92 457 | f 94 101 93 458 | f 101 100 93 459 | f 95 102 101 460 | f 95 101 94 461 | f 96 103 102 462 | f 96 102 95 463 | f 97 104 103 464 | f 97 103 96 465 | f 104 97 29 466 | f 14 105 106 467 | f 14 106 1 468 | f 16 109 15 469 | f 17 110 16 470 | f 110 109 16 471 | f 13 111 17 472 | f 111 110 17 473 | f 112 2 1 474 | f 112 1 106 475 | f 113 4 2 476 | f 113 2 112 477 | f 114 4 113 478 | f 116 11 115 479 | f 11 9 115 480 | f 111 13 116 481 | f 13 11 116 482 | f 117 118 119 483 | f 117 119 120 484 | f 121 122 118 485 | f 121 118 117 486 | f 123 124 122 487 | f 123 122 121 488 | f 108 125 124 489 | f 108 124 123 490 | f 126 127 108 491 | f 127 125 108 492 | f 128 129 126 493 | f 129 127 126 494 | f 130 131 128 495 | f 131 129 128 496 | f 132 133 130 497 | f 133 131 130 498 | f 134 135 120 499 | f 134 120 119 500 | f 136 137 135 501 | f 136 135 134 502 | f 143 144 141 503 | f 144 142 141 504 | f 133 132 143 505 | f 132 144 143 506 | f 118 145 146 507 | f 118 146 119 508 | f 122 147 145 509 | f 122 145 118 510 | f 124 147 122 511 | f 129 149 127 512 | f 131 150 129 513 | f 150 149 129 514 | f 133 151 131 515 | f 151 150 131 516 | f 152 134 119 517 | f 152 119 146 518 | f 153 136 134 519 | f 153 134 152 520 | f 155 143 154 521 | f 143 141 154 522 | f 151 133 155 523 | f 133 143 155 524 | f 156 157 158 525 | f 157 159 158 526 | f 148 162 161 527 | f 163 162 148 528 | f 167 168 166 529 | f 167 166 165 530 | f 169 170 159 531 | f 170 158 159 532 | f 171 172 169 533 | f 172 170 169 534 | f 173 172 171 535 | f 176 177 175 536 | f 178 179 177 537 | f 178 177 176 538 | f 168 167 179 539 | f 168 179 178 540 | f 180 181 182 541 | f 180 182 183 542 | f 184 181 180 543 | f 187 188 186 544 | f 189 190 187 545 | f 190 188 187 546 | f 191 192 183 547 | f 191 183 182 548 | f 193 194 192 549 | f 193 192 191 550 | f 200 201 198 551 | f 201 199 198 552 | f 190 189 200 553 | f 189 201 200 554 | f 202 203 204 555 | f 202 204 205 556 | f 206 207 203 557 | f 206 203 202 558 | f 211 212 209 559 | f 212 210 209 560 | f 213 214 211 561 | f 214 212 211 562 | f 215 216 205 563 | f 215 205 204 564 | f 217 218 216 565 | f 217 216 215 566 | f 224 225 222 567 | f 225 223 222 568 | f 214 213 224 569 | f 213 225 224 570 | f 226 227 228 571 | f 226 228 229 572 | f 230 231 227 573 | f 230 227 226 574 | f 232 233 231 575 | f 232 231 230 576 | f 208 51 233 577 | f 208 233 232 578 | f 235 236 234 579 | f 237 238 235 580 | f 238 236 235 581 | f 239 240 237 582 | f 240 238 237 583 | f 241 242 229 584 | f 241 229 228 585 | f 240 239 245 586 | f 239 246 245 587 | f 242 215 229 588 | f 215 204 229 589 | f 243 217 242 590 | f 217 215 242 591 | f 246 224 222 592 | f 246 222 244 593 | f 239 214 224 594 | f 239 224 246 595 | f 203 226 204 596 | f 226 229 204 597 | f 207 230 203 598 | f 230 226 203 599 | f 232 230 207 600 | f 210 235 234 601 | f 212 237 235 602 | f 212 235 210 603 | f 214 239 237 604 | f 214 237 212 605 | f 216 247 205 606 | f 247 248 205 607 | f 218 249 216 608 | f 249 247 216 609 | f 219 250 218 610 | f 250 249 218 611 | f 220 251 219 612 | f 251 250 219 613 | f 221 252 251 614 | f 221 251 220 615 | f 223 253 252 616 | f 223 252 221 617 | f 225 254 253 618 | f 225 253 223 619 | f 213 255 254 620 | f 213 254 225 621 | f 256 202 248 622 | f 202 205 248 623 | f 257 206 256 624 | f 206 202 256 625 | f 259 211 209 626 | f 259 209 258 627 | f 255 213 211 628 | f 255 211 259 629 | f 247 191 182 630 | f 247 182 248 631 | f 249 193 191 632 | f 249 191 247 633 | f 250 193 249 634 | f 253 198 252 635 | f 254 200 253 636 | f 200 198 253 637 | f 255 190 254 638 | f 190 200 254 639 | f 181 256 248 640 | f 181 248 182 641 | f 190 255 188 642 | f 255 259 188 643 | f 192 169 183 644 | f 169 159 183 645 | f 194 171 192 646 | f 171 169 192 647 | f 196 174 195 648 | f 197 174 196 649 | f 201 178 176 650 | f 201 176 199 651 | f 189 168 178 652 | f 189 178 201 653 | f 157 180 159 654 | f 180 183 159 655 | f 184 180 157 656 | f 166 187 186 657 | f 168 189 187 658 | f 168 187 166 659 | f 170 152 158 660 | f 152 146 158 661 | f 172 153 170 662 | f 153 152 170 663 | f 174 139 173 664 | f 175 139 174 665 | f 179 155 154 666 | f 179 154 177 667 | f 167 151 155 668 | f 167 155 179 669 | f 145 156 146 670 | f 156 158 146 671 | f 147 160 145 672 | f 160 156 145 673 | f 161 160 147 674 | f 149 164 163 675 | f 150 165 164 676 | f 150 164 149 677 | f 151 167 165 678 | f 151 165 150 679 | f 135 112 120 680 | f 112 106 120 681 | f 137 113 135 682 | f 113 112 135 683 | f 138 114 137 684 | f 114 113 137 685 | f 144 116 115 686 | f 144 115 142 687 | f 132 111 116 688 | f 132 116 144 689 | f 105 117 106 690 | f 117 120 106 691 | f 107 121 105 692 | f 121 117 105 693 | f 123 121 107 694 | f 109 128 126 695 | f 110 130 128 696 | f 110 128 109 697 | f 111 132 130 698 | f 111 130 110 699 | f 29 240 245 700 | f 29 245 104 701 | f 241 98 99 702 | f 228 18 98 703 | f 228 98 241 704 | f 236 53 52 705 | f 238 54 53 706 | f 238 53 236 707 | f 240 29 54 708 | f 240 54 238 709 | f 50 231 233 710 | f 49 227 231 711 | f 49 231 50 712 | f 18 228 227 713 | f 18 227 49 714 | f 8 6 7 715 | f 7 6 5 716 | f 114 7 4 717 | f 7 114 138 718 | f 139 7 138 719 | f 140 7 139 720 | f 7 5 4 721 | f 18 49 35 722 | f 20 30 35 723 | f 30 36 35 724 | f 19 20 35 725 | f 50 19 35 726 | f 50 35 49 727 | f 41 34 28 728 | f 41 40 34 729 | f 41 54 29 730 | f 41 27 53 731 | f 41 28 27 732 | f 54 41 53 733 | f 18 79 62 734 | f 80 63 62 735 | f 80 62 79 736 | f 73 71 84 737 | f 73 85 29 738 | f 85 73 84 739 | f 18 55 79 740 | f 56 86 79 741 | f 56 79 55 742 | f 85 90 60 743 | f 85 61 29 744 | f 61 85 60 745 | f 18 62 91 746 | f 74 91 62 747 | f 74 92 91 748 | f 73 97 78 749 | f 97 73 29 750 | f 97 96 78 751 | f 115 9 7 752 | f 142 115 7 753 | f 142 7 140 754 | f 138 137 136 755 | f 141 142 140 756 | f 173 171 194 757 | f 174 173 195 758 | f 195 173 194 759 | f 197 175 174 760 | f 199 176 175 761 | f 199 175 197 762 | f 195 194 193 763 | f 250 195 193 764 | f 251 196 195 765 | f 251 195 250 766 | f 197 196 251 767 | f 198 199 197 768 | f 198 197 252 769 | f 252 197 251 770 | f 219 218 217 771 | f 219 217 243 772 | f 222 223 221 773 | f 244 222 221 774 | f 243 242 241 775 | f 241 99 243 776 | f 243 99 100 777 | f 245 246 244 778 | f 104 245 244 779 | f 104 244 103 780 | f 185 208 232 781 | f 234 208 185 782 | f 184 257 181 783 | f 257 256 181 784 | f 188 258 186 785 | f 188 259 258 786 | f 160 184 156 787 | f 184 157 156 788 | f 165 186 164 789 | f 165 166 186 790 | f 124 161 147 791 | f 125 161 124 792 | f 125 148 161 793 | f 127 163 125 794 | f 149 163 127 795 | f 163 148 125 796 | f 109 126 15 797 | f 234 52 208 798 | f 236 52 234 799 | f 52 51 208 800 | f 233 21 19 801 | f 51 21 233 802 | f 233 19 50 803 | f 138 136 153 804 | f 138 153 172 805 | f 139 138 173 806 | f 173 138 172 807 | f 175 140 139 808 | f 154 141 140 809 | f 177 154 140 810 | f 177 140 175 811 | f 100 219 243 812 | f 101 220 100 813 | f 220 219 100 814 | f 102 220 101 815 | f 103 244 102 816 | f 244 221 102 817 | f 102 221 220 818 | f 269 260 277 819 | f 270 277 260 820 | f 260 261 270 821 | f 261 262 270 822 | f 271 270 262 823 | f 262 263 271 824 | f 263 264 271 825 | f 272 271 264 826 | f 264 265 272 827 | f 273 272 265 828 | f 265 266 273 829 | f 274 273 266 830 | f 266 267 274 831 | f 275 274 267 832 | f 276 275 267 833 | f 267 268 276 834 | f 268 269 276 835 | f 277 276 269 836 | f 277 270 285 837 | f 278 285 270 838 | f 270 271 279 839 | f 279 278 270 840 | f 271 272 279 841 | f 280 279 272 842 | f 272 273 280 843 | f 281 280 273 844 | f 273 274 281 845 | f 282 281 274 846 | f 274 275 282 847 | f 283 282 275 848 | f 275 276 284 849 | f 284 283 275 850 | f 276 277 285 851 | f 285 284 276 852 | f 285 278 293 853 | f 286 293 278 854 | f 278 279 287 855 | f 287 286 278 856 | f 279 280 287 857 | f 288 287 280 858 | f 280 281 288 859 | f 289 288 281 860 | f 281 282 289 861 | f 290 289 282 862 | f 282 283 291 863 | f 291 290 282 864 | f 283 284 292 865 | f 292 291 283 866 | f 284 285 293 867 | f 293 292 284 868 | f 293 286 301 869 | f 294 301 286 870 | f 286 287 295 871 | f 295 294 286 872 | f 287 288 296 873 | f 296 295 287 874 | f 288 289 297 875 | f 297 296 288 876 | f 289 290 297 877 | f 298 297 290 878 | f 290 291 299 879 | f 299 298 290 880 | f 291 292 299 881 | f 300 299 292 882 | f 292 293 300 883 | f 301 300 293 884 | f 301 294 308 885 | f 302 308 294 886 | f 294 295 302 887 | f 303 302 295 888 | f 295 296 304 889 | f 304 303 295 890 | f 297 298 305 891 | f 298 299 306 892 | f 306 305 298 893 | f 299 300 306 894 | f 307 306 300 895 | f 300 301 307 896 | f 308 307 301 897 | f 308 302 315 898 | f 309 315 302 899 | f 302 303 309 900 | f 310 309 303 901 | f 303 304 311 902 | f 311 310 303 903 | f 305 306 313 904 | f 313 312 305 905 | f 306 307 313 906 | f 314 313 307 907 | f 307 308 314 908 | f 315 314 308 909 | f 315 309 320 910 | f 309 310 316 911 | f 310 311 317 912 | f 317 316 310 913 | f 312 313 319 914 | f 319 318 312 915 | f 313 314 319 916 | f 316 317 321 917 | f 322 321 317 918 | f 318 319 324 919 | f 324 323 318 920 | f 321 322 326 921 | f 323 324 326 922 | f 108 261 260 923 | f 260 126 108 924 | f 123 262 261 925 | f 261 108 123 926 | f 123 107 263 927 | f 262 123 263 928 | f 5 6 266 929 | f 265 5 266 930 | f 6 8 267 931 | f 266 6 267 932 | f 15 268 267 933 | f 267 8 15 934 | f 268 15 269 935 | f 126 260 269 936 | f 15 126 269 937 | f 185 206 257 938 | f 185 207 206 939 | f 185 232 207 940 | f 162 257 184 941 | f 162 184 160 942 | f 162 185 257 943 | f 161 162 160 944 | f 186 258 162 945 | f 164 186 162 946 | f 164 162 163 947 | f 258 185 162 948 | f 258 209 185 949 | f 210 234 185 950 | f 209 210 185 951 | f 5 264 3 952 | f 264 5 265 953 | f 264 14 3 954 | f 264 105 14 955 | f 264 107 105 956 | f 263 107 264 957 | f 296 297 305 958 | f 305 304 296 959 | f 304 305 312 960 | f 312 311 304 961 | f 316 320 309 962 | f 320 316 321 963 | f 311 312 317 964 | f 318 317 312 965 | f 320 319 314 966 | f 314 315 320 967 | f 321 325 320 968 | f 325 321 326 969 | f 323 322 317 970 | f 322 323 326 971 | f 317 318 323 972 | f 319 320 325 973 | f 325 324 319 974 | f 324 325 326 975 | #sl -0.2994557099206982 1.3807141495295285 0.1964113386009258 -0.302547238464886 1.373735680583609 0.19611437077175256 1 976 | #sl -0.302547238464886 1.373735680583609 0.19611437077175256 -0.3179173731405764 1.2880726694675424 0.22109901809873245 393 977 | #sl -0.3179173731405764 1.2880726694675424 0.22109901809873245 -0.33269387363748953 1.3173571057934743 0.24046038340901854 388 978 | #sl -0.33269387363748953 1.3173571057934743 0.24046038340901854 -0.33188433558688585 1.3297490374664154 0.28937428962385114 387 979 | #se 259 260 260 261 261 262 262 263 263 264 264 265 265 266 266 267 267 268 268 259 980 | -------------------------------------------------------------------------------- /examples/models/sample.obj: -------------------------------------------------------------------------------- 1 | # Blender3D v249 OBJ File: untitled.blend 2 | # www.blender3d.org 3 | mtllib cube.mtl 4 | v 1.000000 -1.000000 -1.000000 5 | v 1.000000 -1.000000 1.000000 6 | v -1.000000 -1.000000 1.000000 7 | v -1.000000 -1.000000 -1.000000 8 | v 1.000000 1.000000 -1.000000 9 | v 1.000000 1.000000 1.000000 10 | #v 0.999999 1.000000 1.000001 11 | v -1.000000 1.000000 1.000000 12 | v -1.000000 1.000000 -1.000000 13 | vt 0.748573 0.750412 14 | vt 0.749279 0.501284 15 | vt 0.999110 0.501077 16 | vt 0.999455 0.750380 17 | vt 0.250471 0.500702 18 | vt 0.249682 0.749677 19 | vt 0.001085 0.750380 20 | vt 0.001517 0.499994 21 | vt 0.499422 0.500239 22 | vt 0.500149 0.750166 23 | vt 0.748355 0.998230 24 | vt 0.500193 0.998728 25 | vt 0.498993 0.250415 26 | vt 0.748953 0.250920 27 | vn 0.000000 0.000000 -1.000000 28 | vn -1.000000 -0.000000 -0.000000 29 | vn -0.000000 -0.000000 1.000000 30 | vn -0.000001 0.000000 1.000000 31 | vn 1.000000 -0.000000 0.000000 32 | vn 1.000000 0.000000 0.000001 33 | vn 0.000000 1.000000 -0.000000 34 | vn -0.000000 -1.000000 0.000000 35 | usemtl Material_ray.png 36 | s off 37 | f 5/1/1 1/2/1 4/3/1 38 | f 5/1/1 4/3/1 8/4/1 39 | f 3/5/2 7/6/2 8/7/2 40 | f 3/5/2 8/7/2 4/8/2 41 | f 2/9/3 6/10/3 3/5/3 42 | f 6/10/4 7/6/4 3/5/4 43 | f 1/2/5 5/1/5 2/9/5 44 | f 5/1/6 6/10/6 2/9/6 45 | f 5/1/7 8/11/7 6/10/7 46 | f 8/11/7 7/12/7 6/10/7 47 | f 1/2/8 2/9/8 3/13/8 48 | f 1/2/8 3/13/8 4/14/8 49 | -------------------------------------------------------------------------------- /examples/models/suzanne.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.58 (sub 0) OBJ File: '' 2 | # www.blender.org 3 | o Monkey 4 | v 0.437500 0.164063 0.765625 5 | v -0.437500 0.164063 0.765625 6 | v 0.500000 0.093750 0.687500 7 | v -0.500000 0.093750 0.687500 8 | v 0.546875 0.054688 0.578125 9 | v -0.546875 0.054688 0.578125 10 | v 0.351562 -0.023437 0.617188 11 | v -0.351562 -0.023437 0.617188 12 | v 0.351562 0.031250 0.718750 13 | v -0.351562 0.031250 0.718750 14 | v 0.351562 0.132813 0.781250 15 | v -0.351562 0.132813 0.781250 16 | v 0.273438 0.164063 0.796875 17 | v -0.273438 0.164063 0.796875 18 | v 0.203125 0.093750 0.742188 19 | v -0.203125 0.093750 0.742188 20 | v 0.156250 0.054688 0.648438 21 | v -0.156250 0.054688 0.648438 22 | v 0.078125 0.242188 0.656250 23 | v -0.078125 0.242188 0.656250 24 | v 0.140625 0.242188 0.742188 25 | v -0.140625 0.242188 0.742188 26 | v 0.242188 0.242188 0.796875 27 | v -0.242188 0.242188 0.796875 28 | v 0.273438 0.328125 0.796875 29 | v -0.273438 0.328125 0.796875 30 | v 0.203125 0.390625 0.742188 31 | v -0.203125 0.390625 0.742188 32 | v 0.156250 0.437500 0.648437 33 | v -0.156250 0.437500 0.648437 34 | v 0.351562 0.515625 0.617187 35 | v -0.351562 0.515625 0.617187 36 | v 0.351562 0.453125 0.718750 37 | v -0.351562 0.453125 0.718750 38 | v 0.351562 0.359375 0.781250 39 | v -0.351562 0.359375 0.781250 40 | v 0.437500 0.328125 0.765625 41 | v -0.437500 0.328125 0.765625 42 | v 0.500000 0.390625 0.687500 43 | v -0.500000 0.390625 0.687500 44 | v 0.546875 0.437500 0.578125 45 | v -0.546875 0.437500 0.578125 46 | v 0.625000 0.242188 0.562500 47 | v -0.625000 0.242188 0.562500 48 | v 0.562500 0.242188 0.671875 49 | v -0.562500 0.242188 0.671875 50 | v 0.468750 0.242188 0.757812 51 | v -0.468750 0.242188 0.757812 52 | v 0.476562 0.242188 0.773438 53 | v -0.476562 0.242188 0.773438 54 | v 0.445312 0.335938 0.781250 55 | v -0.445312 0.335938 0.781250 56 | v 0.351562 0.375000 0.804688 57 | v -0.351562 0.375000 0.804688 58 | v 0.265625 0.335938 0.820312 59 | v -0.265625 0.335938 0.820312 60 | v 0.226562 0.242188 0.820312 61 | v -0.226562 0.242188 0.820312 62 | v 0.265625 0.156250 0.820312 63 | v -0.265625 0.156250 0.820312 64 | v 0.351562 0.242188 0.828125 65 | v -0.351562 0.242188 0.828125 66 | v 0.351562 0.117188 0.804688 67 | v -0.351562 0.117188 0.804688 68 | v 0.445312 0.156250 0.781250 69 | v -0.445312 0.156250 0.781250 70 | v 0.000000 0.429688 0.742187 71 | v 0.000000 0.351563 0.820312 72 | v 0.000000 -0.679687 0.734375 73 | v 0.000000 -0.320312 0.781250 74 | v 0.000000 -0.187500 0.796875 75 | v 0.000000 -0.773437 0.718750 76 | v 0.000000 0.406250 0.601562 77 | v 0.000000 0.570313 0.570312 78 | v 0.000000 0.898437 -0.546875 79 | v 0.000000 0.562500 -0.851563 80 | v 0.000000 0.070312 -0.828125 81 | v 0.000000 -0.382813 -0.351562 82 | v 0.203125 -0.187500 0.562500 83 | v -0.203125 -0.187500 0.562500 84 | v 0.312500 -0.437500 0.570313 85 | v -0.312500 -0.437500 0.570313 86 | v 0.351562 -0.695312 0.570313 87 | v -0.351562 -0.695312 0.570313 88 | v 0.367188 -0.890625 0.531250 89 | v -0.367188 -0.890625 0.531250 90 | v 0.328125 -0.945312 0.523438 91 | v -0.328125 -0.945312 0.523438 92 | v 0.179688 -0.968750 0.554688 93 | v -0.179688 -0.968750 0.554688 94 | v 0.000000 -0.984375 0.578125 95 | v 0.437500 -0.140625 0.531250 96 | v -0.437500 -0.140625 0.531250 97 | v 0.632812 -0.039062 0.539062 98 | v -0.632812 -0.039062 0.539062 99 | v 0.828125 0.148438 0.445312 100 | v -0.828125 0.148438 0.445312 101 | v 0.859375 0.429688 0.593750 102 | v -0.859375 0.429688 0.593750 103 | v 0.710938 0.484375 0.625000 104 | v -0.710938 0.484375 0.625000 105 | v 0.492188 0.601563 0.687500 106 | v -0.492188 0.601563 0.687500 107 | v 0.320312 0.757813 0.734375 108 | v -0.320312 0.757813 0.734375 109 | v 0.156250 0.718750 0.757812 110 | v -0.156250 0.718750 0.757812 111 | v 0.062500 0.492188 0.750000 112 | v -0.062500 0.492188 0.750000 113 | v 0.164062 0.414063 0.773437 114 | v -0.164062 0.414063 0.773437 115 | v 0.125000 0.304688 0.765625 116 | v -0.125000 0.304688 0.765625 117 | v 0.203125 0.093750 0.742188 118 | v -0.203125 0.093750 0.742188 119 | v 0.375000 0.015625 0.703125 120 | v -0.375000 0.015625 0.703125 121 | v 0.492188 0.062500 0.671875 122 | v -0.492188 0.062500 0.671875 123 | v 0.625000 0.187500 0.648438 124 | v -0.625000 0.187500 0.648438 125 | v 0.640625 0.296875 0.648438 126 | v -0.640625 0.296875 0.648438 127 | v 0.601562 0.375000 0.664062 128 | v -0.601562 0.375000 0.664062 129 | v 0.429688 0.437500 0.718750 130 | v -0.429688 0.437500 0.718750 131 | v 0.250000 0.468750 0.757812 132 | v -0.250000 0.468750 0.757812 133 | v 0.000000 -0.765625 0.734375 134 | v 0.109375 -0.718750 0.734375 135 | v -0.109375 -0.718750 0.734375 136 | v 0.117188 -0.835937 0.710938 137 | v -0.117188 -0.835937 0.710938 138 | v 0.062500 -0.882812 0.695313 139 | v -0.062500 -0.882812 0.695313 140 | v 0.000000 -0.890625 0.687500 141 | v 0.000000 -0.195312 0.750000 142 | v 0.000000 -0.140625 0.742188 143 | v 0.101562 -0.148437 0.742188 144 | v -0.101562 -0.148437 0.742188 145 | v 0.125000 -0.226562 0.750000 146 | v -0.125000 -0.226562 0.750000 147 | v 0.085938 -0.289062 0.742188 148 | v -0.085938 -0.289062 0.742188 149 | v 0.398438 -0.046875 0.671875 150 | v -0.398438 -0.046875 0.671875 151 | v 0.617188 0.054688 0.625000 152 | v -0.617188 0.054688 0.625000 153 | v 0.726562 0.203125 0.601562 154 | v -0.726562 0.203125 0.601562 155 | v 0.742188 0.375000 0.656250 156 | v -0.742188 0.375000 0.656250 157 | v 0.687500 0.414063 0.726562 158 | v -0.687500 0.414063 0.726562 159 | v 0.437500 0.546875 0.796875 160 | v -0.437500 0.546875 0.796875 161 | v 0.312500 0.640625 0.835937 162 | v -0.312500 0.640625 0.835937 163 | v 0.203125 0.617188 0.851562 164 | v -0.203125 0.617188 0.851562 165 | v 0.101562 0.429688 0.843750 166 | v -0.101562 0.429688 0.843750 167 | v 0.125000 -0.101562 0.812500 168 | v -0.125000 -0.101562 0.812500 169 | v 0.210938 -0.445312 0.710938 170 | v -0.210938 -0.445312 0.710938 171 | v 0.250000 -0.703125 0.687500 172 | v -0.250000 -0.703125 0.687500 173 | v 0.265625 -0.820312 0.664063 174 | v -0.265625 -0.820312 0.664063 175 | v 0.234375 -0.914062 0.632813 176 | v -0.234375 -0.914062 0.632813 177 | v 0.164062 -0.929687 0.632813 178 | v -0.164062 -0.929687 0.632813 179 | v 0.000000 -0.945312 0.640625 180 | v 0.000000 0.046875 0.726562 181 | v 0.000000 0.210938 0.765625 182 | v 0.328125 0.476563 0.742187 183 | v -0.328125 0.476563 0.742187 184 | v 0.164062 0.140625 0.750000 185 | v -0.164062 0.140625 0.750000 186 | v 0.132812 0.210938 0.757812 187 | v -0.132812 0.210938 0.757812 188 | v 0.117188 -0.687500 0.734375 189 | v -0.117188 -0.687500 0.734375 190 | v 0.078125 -0.445312 0.750000 191 | v -0.078125 -0.445312 0.750000 192 | v 0.000000 -0.445312 0.750000 193 | v 0.000000 -0.328125 0.742188 194 | v 0.093750 -0.273437 0.781250 195 | v -0.093750 -0.273437 0.781250 196 | v 0.132812 -0.226562 0.796875 197 | v -0.132812 -0.226562 0.796875 198 | v 0.109375 -0.132812 0.781250 199 | v -0.109375 -0.132812 0.781250 200 | v 0.039062 -0.125000 0.781250 201 | v -0.039062 -0.125000 0.781250 202 | v 0.000000 -0.203125 0.828125 203 | v 0.046875 -0.148437 0.812500 204 | v -0.046875 -0.148437 0.812500 205 | v 0.093750 -0.156250 0.812500 206 | v -0.093750 -0.156250 0.812500 207 | v 0.109375 -0.226562 0.828125 208 | v -0.109375 -0.226562 0.828125 209 | v 0.078125 -0.250000 0.804688 210 | v -0.078125 -0.250000 0.804688 211 | v 0.000000 -0.289062 0.804688 212 | v 0.257812 -0.312500 0.554688 213 | v -0.257812 -0.312500 0.554688 214 | v 0.164062 -0.242187 0.710938 215 | v -0.164062 -0.242187 0.710938 216 | v 0.179688 -0.312500 0.710938 217 | v -0.179688 -0.312500 0.710938 218 | v 0.234375 -0.250000 0.554688 219 | v -0.234375 -0.250000 0.554688 220 | v 0.000000 -0.875000 0.687500 221 | v 0.046875 -0.867187 0.687500 222 | v -0.046875 -0.867187 0.687500 223 | v 0.093750 -0.820312 0.710938 224 | v -0.093750 -0.820312 0.710938 225 | v 0.093750 -0.742187 0.726563 226 | v -0.093750 -0.742187 0.726563 227 | v 0.000000 -0.781250 0.656250 228 | v 0.093750 -0.750000 0.664063 229 | v -0.093750 -0.750000 0.664063 230 | v 0.093750 -0.812500 0.640625 231 | v -0.093750 -0.812500 0.640625 232 | v 0.046875 -0.851562 0.632813 233 | v -0.046875 -0.851562 0.632813 234 | v 0.000000 -0.859375 0.632813 235 | v 0.171875 0.218750 0.781250 236 | v -0.171875 0.218750 0.781250 237 | v 0.187500 0.156250 0.773438 238 | v -0.187500 0.156250 0.773438 239 | v 0.335938 0.429688 0.757812 240 | v -0.335938 0.429688 0.757812 241 | v 0.273438 0.421875 0.773437 242 | v -0.273438 0.421875 0.773437 243 | v 0.421875 0.398438 0.773437 244 | v -0.421875 0.398438 0.773437 245 | v 0.562500 0.351563 0.695312 246 | v -0.562500 0.351563 0.695312 247 | v 0.585938 0.289063 0.687500 248 | v -0.585938 0.289063 0.687500 249 | v 0.578125 0.195313 0.679688 250 | v -0.578125 0.195313 0.679688 251 | v 0.476562 0.101563 0.718750 252 | v -0.476562 0.101563 0.718750 253 | v 0.375000 0.062500 0.742188 254 | v -0.375000 0.062500 0.742188 255 | v 0.226562 0.109375 0.781250 256 | v -0.226562 0.109375 0.781250 257 | v 0.179688 0.296875 0.781250 258 | v -0.179688 0.296875 0.781250 259 | v 0.210938 0.375000 0.781250 260 | v -0.210938 0.375000 0.781250 261 | v 0.234375 0.359375 0.757812 262 | v -0.234375 0.359375 0.757812 263 | v 0.195312 0.296875 0.757812 264 | v -0.195312 0.296875 0.757812 265 | v 0.242188 0.125000 0.757812 266 | v -0.242188 0.125000 0.757812 267 | v 0.375000 0.085938 0.726562 268 | v -0.375000 0.085938 0.726562 269 | v 0.460938 0.117188 0.703125 270 | v -0.460938 0.117188 0.703125 271 | v 0.546875 0.210938 0.671875 272 | v -0.546875 0.210938 0.671875 273 | v 0.554688 0.281250 0.671875 274 | v -0.554688 0.281250 0.671875 275 | v 0.531250 0.335938 0.679688 276 | v -0.531250 0.335938 0.679688 277 | v 0.414062 0.390625 0.750000 278 | v -0.414062 0.390625 0.750000 279 | v 0.281250 0.398438 0.765625 280 | v -0.281250 0.398438 0.765625 281 | v 0.335938 0.406250 0.750000 282 | v -0.335938 0.406250 0.750000 283 | v 0.203125 0.171875 0.750000 284 | v -0.203125 0.171875 0.750000 285 | v 0.195312 0.226563 0.750000 286 | v -0.195312 0.226563 0.750000 287 | v 0.109375 0.460938 0.609375 288 | v -0.109375 0.460938 0.609375 289 | v 0.195312 0.664063 0.617187 290 | v -0.195312 0.664063 0.617187 291 | v 0.335938 0.687500 0.593750 292 | v -0.335938 0.687500 0.593750 293 | v 0.484375 0.554688 0.554687 294 | v -0.484375 0.554688 0.554687 295 | v 0.679688 0.453125 0.492187 296 | v -0.679688 0.453125 0.492187 297 | v 0.796875 0.406250 0.460937 298 | v -0.796875 0.406250 0.460937 299 | v 0.773438 0.164063 0.375000 300 | v -0.773438 0.164063 0.375000 301 | v 0.601562 0.000000 0.414062 302 | v -0.601562 0.000000 0.414062 303 | v 0.437500 -0.093750 0.468750 304 | v -0.437500 -0.093750 0.468750 305 | v 0.000000 0.898438 0.289062 306 | v 0.000000 0.984375 -0.078125 307 | v 0.000000 -0.195313 -0.671875 308 | v 0.000000 -0.460938 0.187500 309 | v 0.000000 -0.976562 0.460938 310 | v 0.000000 -0.804688 0.343750 311 | v 0.000000 -0.570312 0.320313 312 | v 0.000000 -0.484375 0.281250 313 | v 0.851562 0.234375 0.054687 314 | v -0.851562 0.234375 0.054687 315 | v 0.859375 0.320312 -0.046875 316 | v -0.859375 0.320312 -0.046875 317 | v 0.773438 0.265625 -0.437500 318 | v -0.773438 0.265625 -0.437500 319 | v 0.460938 0.437500 -0.703125 320 | v -0.460938 0.437500 -0.703125 321 | v 0.734375 -0.046875 0.070312 322 | v -0.734375 -0.046875 0.070312 323 | v 0.593750 -0.125000 -0.164062 324 | v -0.593750 -0.125000 -0.164062 325 | v 0.640625 -0.007813 -0.429688 326 | v -0.640625 -0.007813 -0.429688 327 | v 0.335938 0.054687 -0.664062 328 | v -0.335938 0.054687 -0.664062 329 | v 0.234375 -0.351562 0.406250 330 | v -0.234375 -0.351562 0.406250 331 | v 0.179688 -0.414062 0.257813 332 | v -0.179688 -0.414062 0.257813 333 | v 0.289062 -0.710938 0.382813 334 | v -0.289062 -0.710938 0.382813 335 | v 0.250000 -0.500000 0.390625 336 | v -0.250000 -0.500000 0.390625 337 | v 0.328125 -0.914062 0.398438 338 | v -0.328125 -0.914062 0.398438 339 | v 0.140625 -0.757812 0.367188 340 | v -0.140625 -0.757812 0.367188 341 | v 0.125000 -0.539062 0.359375 342 | v -0.125000 -0.539062 0.359375 343 | v 0.164062 -0.945312 0.437500 344 | v -0.164062 -0.945312 0.437500 345 | v 0.218750 -0.281250 0.429688 346 | v -0.218750 -0.281250 0.429688 347 | v 0.210938 -0.226562 0.468750 348 | v -0.210938 -0.226562 0.468750 349 | v 0.203125 -0.171875 0.500000 350 | v -0.203125 -0.171875 0.500000 351 | v 0.210938 -0.390625 0.164063 352 | v -0.210938 -0.390625 0.164063 353 | v 0.296875 -0.312500 -0.265625 354 | v -0.296875 -0.312500 -0.265625 355 | v 0.343750 -0.148438 -0.539062 356 | v -0.343750 -0.148438 -0.539062 357 | v 0.453125 0.867188 -0.382813 358 | v -0.453125 0.867188 -0.382813 359 | v 0.453125 0.929688 -0.070313 360 | v -0.453125 0.929688 -0.070313 361 | v 0.453125 0.851562 0.234375 362 | v -0.453125 0.851562 0.234375 363 | v 0.460938 0.523438 0.429687 364 | v -0.460938 0.523438 0.429687 365 | v 0.726562 0.406250 0.335937 366 | v -0.726562 0.406250 0.335937 367 | v 0.632812 0.453125 0.281250 368 | v -0.632812 0.453125 0.281250 369 | v 0.640625 0.703125 0.054687 370 | v -0.640625 0.703125 0.054687 371 | v 0.796875 0.562500 0.125000 372 | v -0.796875 0.562500 0.125000 373 | v 0.796875 0.617188 -0.117188 374 | v -0.796875 0.617188 -0.117188 375 | v 0.640625 0.750000 -0.195313 376 | v -0.640625 0.750000 -0.195313 377 | v 0.640625 0.679687 -0.445313 378 | v -0.640625 0.679687 -0.445313 379 | v 0.796875 0.539062 -0.359375 380 | v -0.796875 0.539062 -0.359375 381 | v 0.617188 0.328125 -0.585938 382 | v -0.617188 0.328125 -0.585938 383 | v 0.484375 0.023437 -0.546875 384 | v -0.484375 0.023437 -0.546875 385 | v 0.820312 0.328125 -0.203125 386 | v -0.820312 0.328125 -0.203125 387 | v 0.406250 -0.171875 0.148438 388 | v -0.406250 -0.171875 0.148438 389 | v 0.429688 -0.195313 -0.210937 390 | v -0.429688 -0.195313 -0.210937 391 | v 0.890625 0.406250 -0.234375 392 | v -0.890625 0.406250 -0.234375 393 | v 0.773438 -0.140625 -0.125000 394 | v -0.773438 -0.140625 -0.125000 395 | v 1.039062 -0.101563 -0.328125 396 | v -1.039062 -0.101563 -0.328125 397 | v 1.281250 0.054687 -0.429688 398 | v -1.281250 0.054687 -0.429688 399 | v 1.351562 0.320312 -0.421875 400 | v -1.351562 0.320312 -0.421875 401 | v 1.234375 0.507812 -0.421875 402 | v -1.234375 0.507812 -0.421875 403 | v 1.023438 0.476562 -0.312500 404 | v -1.023438 0.476562 -0.312500 405 | v 1.015625 0.414062 -0.289063 406 | v -1.015625 0.414062 -0.289063 407 | v 1.187500 0.437500 -0.390625 408 | v -1.187500 0.437500 -0.390625 409 | v 1.265625 0.289062 -0.406250 410 | v -1.265625 0.289062 -0.406250 411 | v 1.210938 0.078125 -0.406250 412 | v -1.210938 0.078125 -0.406250 413 | v 1.031250 -0.039063 -0.304688 414 | v -1.031250 -0.039063 -0.304688 415 | v 0.828125 -0.070313 -0.132812 416 | v -0.828125 -0.070313 -0.132812 417 | v 0.921875 0.359375 -0.218750 418 | v -0.921875 0.359375 -0.218750 419 | v 0.945312 0.304687 -0.289063 420 | v -0.945312 0.304687 -0.289063 421 | v 0.882812 -0.023438 -0.210938 422 | v -0.882812 -0.023438 -0.210938 423 | v 1.039062 -0.000000 -0.367188 424 | v -1.039062 -0.000000 -0.367188 425 | v 1.187500 0.093750 -0.445312 426 | v -1.187500 0.093750 -0.445312 427 | v 1.234375 0.250000 -0.445313 428 | v -1.234375 0.250000 -0.445313 429 | v 1.171875 0.359375 -0.437500 430 | v -1.171875 0.359375 -0.437500 431 | v 1.023438 0.343750 -0.359375 432 | v -1.023438 0.343750 -0.359375 433 | v 0.843750 0.289062 -0.210938 434 | v -0.843750 0.289062 -0.210938 435 | v 0.835938 0.171875 -0.273438 436 | v -0.835938 0.171875 -0.273438 437 | v 0.757812 0.093750 -0.273438 438 | v -0.757812 0.093750 -0.273438 439 | v 0.820312 0.085937 -0.273438 440 | v -0.820312 0.085937 -0.273438 441 | v 0.843750 0.015625 -0.273438 442 | v -0.843750 0.015625 -0.273438 443 | v 0.812500 -0.015625 -0.273438 444 | v -0.812500 -0.015625 -0.273438 445 | v 0.726562 -0.000000 -0.070312 446 | v -0.726562 -0.000000 -0.070312 447 | v 0.718750 -0.023438 -0.171875 448 | v -0.718750 -0.023438 -0.171875 449 | v 0.718750 0.039062 -0.187500 450 | v -0.718750 0.039062 -0.187500 451 | v 0.796875 0.203125 -0.210938 452 | v -0.796875 0.203125 -0.210938 453 | v 0.890625 0.242187 -0.265625 454 | v -0.890625 0.242187 -0.265625 455 | v 0.890625 0.234375 -0.320313 456 | v -0.890625 0.234375 -0.320313 457 | v 0.812500 -0.015625 -0.320312 458 | v -0.812500 -0.015625 -0.320312 459 | v 0.851562 0.015625 -0.320312 460 | v -0.851562 0.015625 -0.320312 461 | v 0.828125 0.078125 -0.320312 462 | v -0.828125 0.078125 -0.320312 463 | v 0.765625 0.093750 -0.320312 464 | v -0.765625 0.093750 -0.320312 465 | v 0.843750 0.171875 -0.320312 466 | v -0.843750 0.171875 -0.320312 467 | v 1.039062 0.328125 -0.414063 468 | v -1.039062 0.328125 -0.414063 469 | v 1.187500 0.343750 -0.484375 470 | v -1.187500 0.343750 -0.484375 471 | v 1.257812 0.242187 -0.492188 472 | v -1.257812 0.242187 -0.492188 473 | v 1.210938 0.085937 -0.484375 474 | v -1.210938 0.085937 -0.484375 475 | v 1.046875 -0.000000 -0.421875 476 | v -1.046875 -0.000000 -0.421875 477 | v 0.882812 -0.015625 -0.265625 478 | v -0.882812 -0.015625 -0.265625 479 | v 0.953125 0.289062 -0.343750 480 | v -0.953125 0.289062 -0.343750 481 | v 0.890625 0.109375 -0.328125 482 | v -0.890625 0.109375 -0.328125 483 | v 0.937500 0.062500 -0.335938 484 | v -0.937500 0.062500 -0.335938 485 | v 1.000000 0.125000 -0.367188 486 | v -1.000000 0.125000 -0.367188 487 | v 0.960938 0.171875 -0.351562 488 | v -0.960938 0.171875 -0.351562 489 | v 1.015625 0.234375 -0.375000 490 | v -1.015625 0.234375 -0.375000 491 | v 1.054688 0.187500 -0.382812 492 | v -1.054688 0.187500 -0.382812 493 | v 1.109375 0.210937 -0.390625 494 | v -1.109375 0.210937 -0.390625 495 | v 1.085938 0.273437 -0.390625 496 | v -1.085938 0.273437 -0.390625 497 | v 1.023438 0.437500 -0.484375 498 | v -1.023438 0.437500 -0.484375 499 | v 1.250000 0.468750 -0.546875 500 | v -1.250000 0.468750 -0.546875 501 | v 1.367188 0.296875 -0.500000 502 | v -1.367188 0.296875 -0.500000 503 | v 1.312500 0.054687 -0.531250 504 | v -1.312500 0.054687 -0.531250 505 | v 1.039062 -0.085938 -0.492188 506 | v -1.039062 -0.085938 -0.492188 507 | v 0.789062 -0.125000 -0.328125 508 | v -0.789062 -0.125000 -0.328125 509 | v 0.859375 0.382812 -0.382813 510 | v -0.859375 0.382812 -0.382813 511 | usemtl (null) 512 | s off 513 | f 47 1 3 514 | f 47 3 45 515 | f 4 2 48 516 | f 4 48 46 517 | f 45 3 5 518 | f 45 5 43 519 | f 6 4 46 520 | f 6 46 44 521 | f 3 9 7 522 | f 3 7 5 523 | f 8 10 4 524 | f 8 4 6 525 | f 1 11 9 526 | f 1 9 3 527 | f 10 12 2 528 | f 10 2 4 529 | f 11 13 15 530 | f 11 15 9 531 | f 16 14 12 532 | f 16 12 10 533 | f 9 15 17 534 | f 9 17 7 535 | f 18 16 10 536 | f 18 10 8 537 | f 15 21 19 538 | f 15 19 17 539 | f 20 22 16 540 | f 20 16 18 541 | f 13 23 21 542 | f 13 21 15 543 | f 22 24 14 544 | f 22 14 16 545 | f 23 25 27 546 | f 23 27 21 547 | f 28 26 24 548 | f 28 24 22 549 | f 21 27 29 550 | f 21 29 19 551 | f 30 28 22 552 | f 30 22 20 553 | f 27 33 31 554 | f 27 31 29 555 | f 32 34 28 556 | f 32 28 30 557 | f 25 35 33 558 | f 25 33 27 559 | f 34 36 26 560 | f 34 26 28 561 | f 35 37 39 562 | f 35 39 33 563 | f 40 38 36 564 | f 40 36 34 565 | f 33 39 41 566 | f 33 41 31 567 | f 42 40 34 568 | f 42 34 32 569 | f 39 45 43 570 | f 39 43 41 571 | f 44 46 40 572 | f 44 40 42 573 | f 37 47 45 574 | f 37 45 39 575 | f 46 48 38 576 | f 46 38 40 577 | f 47 37 51 578 | f 47 51 49 579 | f 52 38 48 580 | f 52 48 50 581 | f 37 35 53 582 | f 37 53 51 583 | f 54 36 38 584 | f 54 38 52 585 | f 35 25 55 586 | f 35 55 53 587 | f 56 26 36 588 | f 56 36 54 589 | f 25 23 57 590 | f 25 57 55 591 | f 58 24 26 592 | f 58 26 56 593 | f 23 13 59 594 | f 23 59 57 595 | f 60 14 24 596 | f 60 24 58 597 | f 13 11 63 598 | f 13 63 59 599 | f 64 12 14 600 | f 64 14 60 601 | f 11 1 65 602 | f 11 65 63 603 | f 66 2 12 604 | f 66 12 64 605 | f 1 47 49 606 | f 1 49 65 607 | f 50 48 2 608 | f 50 2 66 609 | f 61 65 49 610 | f 50 66 62 611 | f 63 65 61 612 | f 62 66 64 613 | f 61 59 63 614 | f 64 60 62 615 | f 61 57 59 616 | f 60 58 62 617 | f 61 55 57 618 | f 58 56 62 619 | f 61 53 55 620 | f 56 54 62 621 | f 61 51 53 622 | f 54 52 62 623 | f 61 49 51 624 | f 52 50 62 625 | f 89 174 176 626 | f 89 176 91 627 | f 176 175 90 628 | f 176 90 91 629 | f 87 172 174 630 | f 87 174 89 631 | f 175 173 88 632 | f 175 88 90 633 | f 85 170 172 634 | f 85 172 87 635 | f 173 171 86 636 | f 173 86 88 637 | f 83 168 170 638 | f 83 170 85 639 | f 171 169 84 640 | f 171 84 86 641 | f 81 166 168 642 | f 81 168 83 643 | f 169 167 82 644 | f 169 82 84 645 | f 79 92 146 646 | f 79 146 164 647 | f 147 93 80 648 | f 147 80 165 649 | f 92 94 148 650 | f 92 148 146 651 | f 149 95 93 652 | f 149 93 147 653 | f 94 96 150 654 | f 94 150 148 655 | f 151 97 95 656 | f 151 95 149 657 | f 96 98 152 658 | f 96 152 150 659 | f 153 99 97 660 | f 153 97 151 661 | f 98 100 154 662 | f 98 154 152 663 | f 155 101 99 664 | f 155 99 153 665 | f 100 102 156 666 | f 100 156 154 667 | f 157 103 101 668 | f 157 101 155 669 | f 102 104 158 670 | f 102 158 156 671 | f 159 105 103 672 | f 159 103 157 673 | f 104 106 160 674 | f 104 160 158 675 | f 161 107 105 676 | f 161 105 159 677 | f 106 108 162 678 | f 106 162 160 679 | f 163 109 107 680 | f 163 107 161 681 | f 108 67 68 682 | f 108 68 162 683 | f 68 67 109 684 | f 68 109 163 685 | f 110 128 160 686 | f 110 160 162 687 | f 161 129 111 688 | f 161 111 163 689 | f 128 179 158 690 | f 128 158 160 691 | f 159 180 129 692 | f 159 129 161 693 | f 126 156 158 694 | f 126 158 179 695 | f 159 157 127 696 | f 159 127 180 697 | f 124 154 156 698 | f 124 156 126 699 | f 157 155 125 700 | f 157 125 127 701 | f 122 152 154 702 | f 122 154 124 703 | f 155 153 123 704 | f 155 123 125 705 | f 120 150 152 706 | f 120 152 122 707 | f 153 151 121 708 | f 153 121 123 709 | f 118 148 150 710 | f 118 150 120 711 | f 151 149 119 712 | f 151 119 121 713 | f 116 146 148 714 | f 116 148 118 715 | f 149 147 117 716 | f 149 117 119 717 | f 114 164 146 718 | f 114 146 116 719 | f 147 165 115 720 | f 147 115 117 721 | f 114 181 177 722 | f 114 177 164 723 | f 177 182 115 724 | f 177 115 165 725 | f 110 162 68 726 | f 110 68 112 727 | f 68 163 111 728 | f 68 111 113 729 | f 112 68 178 730 | f 112 178 183 731 | f 178 68 113 732 | f 178 113 184 733 | f 177 181 183 734 | f 177 183 178 735 | f 184 182 177 736 | f 184 177 178 737 | f 135 137 176 738 | f 135 176 174 739 | f 176 137 136 740 | f 176 136 175 741 | f 133 135 174 742 | f 133 174 172 743 | f 175 136 134 744 | f 175 134 173 745 | f 131 133 172 746 | f 131 172 170 747 | f 173 134 132 748 | f 173 132 171 749 | f 166 187 185 750 | f 166 185 168 751 | f 186 188 167 752 | f 186 167 169 753 | f 131 170 168 754 | f 131 168 185 755 | f 169 171 132 756 | f 169 132 186 757 | f 144 190 189 758 | f 144 189 187 759 | f 189 190 145 760 | f 189 145 188 761 | f 185 187 189 762 | f 185 189 69 763 | f 189 188 186 764 | f 189 186 69 765 | f 130 131 185 766 | f 130 185 69 767 | f 186 132 130 768 | f 186 130 69 769 | f 142 193 191 770 | f 142 191 144 771 | f 192 194 143 772 | f 192 143 145 773 | f 140 195 193 774 | f 140 193 142 775 | f 194 196 141 776 | f 194 141 143 777 | f 139 197 195 778 | f 139 195 140 779 | f 196 198 139 780 | f 196 139 141 781 | f 138 71 197 782 | f 138 197 139 783 | f 198 71 138 784 | f 198 138 139 785 | f 190 144 191 786 | f 190 191 70 787 | f 192 145 190 788 | f 192 190 70 789 | f 70 191 206 790 | f 70 206 208 791 | f 207 192 70 792 | f 207 70 208 793 | f 71 199 200 794 | f 71 200 197 795 | f 201 199 71 796 | f 201 71 198 797 | f 197 200 202 798 | f 197 202 195 799 | f 203 201 198 800 | f 203 198 196 801 | f 195 202 204 802 | f 195 204 193 803 | f 205 203 196 804 | f 205 196 194 805 | f 193 204 206 806 | f 193 206 191 807 | f 207 205 194 808 | f 207 194 192 809 | f 199 204 202 810 | f 199 202 200 811 | f 203 205 199 812 | f 203 199 201 813 | f 199 208 206 814 | f 199 206 204 815 | f 207 208 199 816 | f 207 199 205 817 | f 139 140 164 818 | f 139 164 177 819 | f 165 141 139 820 | f 165 139 177 821 | f 140 142 211 822 | f 140 211 164 823 | f 212 143 141 824 | f 212 141 165 825 | f 142 144 213 826 | f 142 213 211 827 | f 214 145 143 828 | f 214 143 212 829 | f 144 187 166 830 | f 144 166 213 831 | f 167 188 145 832 | f 167 145 214 833 | f 81 209 213 834 | f 81 213 166 835 | f 214 210 82 836 | f 214 82 167 837 | f 209 215 211 838 | f 209 211 213 839 | f 212 216 210 840 | f 212 210 214 841 | f 79 164 211 842 | f 79 211 215 843 | f 212 165 80 844 | f 212 80 216 845 | f 131 130 72 846 | f 131 72 222 847 | f 72 130 132 848 | f 72 132 223 849 | f 133 131 222 850 | f 133 222 220 851 | f 223 132 134 852 | f 223 134 221 853 | f 135 133 220 854 | f 135 220 218 855 | f 221 134 136 856 | f 221 136 219 857 | f 137 135 218 858 | f 137 218 217 859 | f 219 136 137 860 | f 219 137 217 861 | f 217 218 229 862 | f 217 229 231 863 | f 230 219 217 864 | f 230 217 231 865 | f 218 220 227 866 | f 218 227 229 867 | f 228 221 219 868 | f 228 219 230 869 | f 220 222 225 870 | f 220 225 227 871 | f 226 223 221 872 | f 226 221 228 873 | f 222 72 224 874 | f 222 224 225 875 | f 224 72 223 876 | f 224 223 226 877 | f 224 231 229 878 | f 224 229 225 879 | f 230 231 224 880 | f 230 224 226 881 | f 225 229 227 882 | f 228 230 226 883 | f 183 181 234 884 | f 183 234 232 885 | f 235 182 184 886 | f 235 184 233 887 | f 112 183 232 888 | f 112 232 254 889 | f 233 184 113 890 | f 233 113 255 891 | f 110 112 254 892 | f 110 254 256 893 | f 255 113 111 894 | f 255 111 257 895 | f 181 114 252 896 | f 181 252 234 897 | f 253 115 182 898 | f 253 182 235 899 | f 114 116 250 900 | f 114 250 252 901 | f 251 117 115 902 | f 251 115 253 903 | f 116 118 248 904 | f 116 248 250 905 | f 249 119 117 906 | f 249 117 251 907 | f 118 120 246 908 | f 118 246 248 909 | f 247 121 119 910 | f 247 119 249 911 | f 120 122 244 912 | f 120 244 246 913 | f 245 123 121 914 | f 245 121 247 915 | f 122 124 242 916 | f 122 242 244 917 | f 243 125 123 918 | f 243 123 245 919 | f 124 126 240 920 | f 124 240 242 921 | f 241 127 125 922 | f 241 125 243 923 | f 126 179 236 924 | f 126 236 240 925 | f 237 180 127 926 | f 237 127 241 927 | f 179 128 238 928 | f 179 238 236 929 | f 239 129 180 930 | f 239 180 237 931 | f 128 110 256 932 | f 128 256 238 933 | f 257 111 129 934 | f 257 129 239 935 | f 238 256 258 936 | f 238 258 276 937 | f 259 257 239 938 | f 259 239 277 939 | f 236 238 276 940 | f 236 276 278 941 | f 277 239 237 942 | f 277 237 279 943 | f 240 236 278 944 | f 240 278 274 945 | f 279 237 241 946 | f 279 241 275 947 | f 242 240 274 948 | f 242 274 272 949 | f 275 241 243 950 | f 275 243 273 951 | f 244 242 272 952 | f 244 272 270 953 | f 273 243 245 954 | f 273 245 271 955 | f 246 244 270 956 | f 246 270 268 957 | f 271 245 247 958 | f 271 247 269 959 | f 248 246 268 960 | f 248 268 266 961 | f 269 247 249 962 | f 269 249 267 963 | f 250 248 266 964 | f 250 266 264 965 | f 267 249 251 966 | f 267 251 265 967 | f 252 250 264 968 | f 252 264 262 969 | f 265 251 253 970 | f 265 253 263 971 | f 234 252 262 972 | f 234 262 280 973 | f 263 253 235 974 | f 263 235 281 975 | f 256 254 260 976 | f 256 260 258 977 | f 261 255 257 978 | f 261 257 259 979 | f 254 232 282 980 | f 254 282 260 981 | f 283 233 255 982 | f 283 255 261 983 | f 232 234 280 984 | f 232 280 282 985 | f 281 235 233 986 | f 281 233 283 987 | f 67 108 284 988 | f 67 284 73 989 | f 285 109 67 990 | f 285 67 73 991 | f 108 106 286 992 | f 108 286 284 993 | f 287 107 109 994 | f 287 109 285 995 | f 106 104 288 996 | f 106 288 286 997 | f 289 105 107 998 | f 289 107 287 999 | f 104 102 290 1000 | f 104 290 288 1001 | f 291 103 105 1002 | f 291 105 289 1003 | f 102 100 292 1004 | f 102 292 290 1005 | f 293 101 103 1006 | f 293 103 291 1007 | f 100 98 294 1008 | f 100 294 292 1009 | f 295 99 101 1010 | f 295 101 293 1011 | f 98 96 296 1012 | f 98 296 294 1013 | f 297 97 99 1014 | f 297 99 295 1015 | f 96 94 298 1016 | f 96 298 296 1017 | f 299 95 97 1018 | f 299 97 297 1019 | f 94 92 300 1020 | f 94 300 298 1021 | f 301 93 95 1022 | f 301 95 299 1023 | f 308 309 328 1024 | f 308 328 338 1025 | f 329 309 308 1026 | f 329 308 339 1027 | f 307 308 338 1028 | f 307 338 336 1029 | f 339 308 307 1030 | f 339 307 337 1031 | f 306 307 336 1032 | f 306 336 340 1033 | f 337 307 306 1034 | f 337 306 341 1035 | f 89 91 306 1036 | f 89 306 340 1037 | f 306 91 90 1038 | f 306 90 341 1039 | f 87 89 340 1040 | f 87 340 334 1041 | f 341 90 88 1042 | f 341 88 335 1043 | f 85 87 334 1044 | f 85 334 330 1045 | f 335 88 86 1046 | f 335 86 331 1047 | f 83 85 330 1048 | f 83 330 332 1049 | f 331 86 84 1050 | f 331 84 333 1051 | f 330 336 338 1052 | f 330 338 332 1053 | f 339 337 331 1054 | f 339 331 333 1055 | f 330 334 340 1056 | f 330 340 336 1057 | f 341 335 331 1058 | f 341 331 337 1059 | f 326 332 338 1060 | f 326 338 328 1061 | f 339 333 327 1062 | f 339 327 329 1063 | f 81 83 332 1064 | f 81 332 326 1065 | f 333 84 82 1066 | f 333 82 327 1067 | f 209 342 344 1068 | f 209 344 215 1069 | f 345 343 210 1070 | f 345 210 216 1071 | f 81 326 342 1072 | f 81 342 209 1073 | f 343 327 82 1074 | f 343 82 210 1075 | f 79 215 344 1076 | f 79 344 346 1077 | f 345 216 80 1078 | f 345 80 347 1079 | f 79 346 300 1080 | f 79 300 92 1081 | f 301 347 80 1082 | f 301 80 93 1083 | f 77 324 352 1084 | f 77 352 304 1085 | f 353 325 77 1086 | f 353 77 304 1087 | f 304 352 350 1088 | f 304 350 78 1089 | f 351 353 304 1090 | f 351 304 78 1091 | f 78 350 348 1092 | f 78 348 305 1093 | f 349 351 78 1094 | f 349 78 305 1095 | f 305 348 328 1096 | f 305 328 309 1097 | f 329 349 305 1098 | f 329 305 309 1099 | f 326 328 348 1100 | f 326 348 342 1101 | f 349 329 327 1102 | f 349 327 343 1103 | f 296 298 318 1104 | f 296 318 310 1105 | f 319 299 297 1106 | f 319 297 311 1107 | f 76 316 324 1108 | f 76 324 77 1109 | f 325 317 76 1110 | f 325 76 77 1111 | f 302 358 356 1112 | f 302 356 303 1113 | f 357 359 302 1114 | f 357 302 303 1115 | f 303 356 354 1116 | f 303 354 75 1117 | f 355 357 303 1118 | f 355 303 75 1119 | f 75 354 316 1120 | f 75 316 76 1121 | f 317 355 75 1122 | f 317 75 76 1123 | f 292 294 362 1124 | f 292 362 364 1125 | f 363 295 293 1126 | f 363 293 365 1127 | f 364 362 368 1128 | f 364 368 366 1129 | f 369 363 365 1130 | f 369 365 367 1131 | f 366 368 370 1132 | f 366 370 372 1133 | f 371 369 367 1134 | f 371 367 373 1135 | f 372 370 376 1136 | f 372 376 374 1137 | f 377 371 373 1138 | f 377 373 375 1139 | f 314 378 374 1140 | f 314 374 376 1141 | f 375 379 315 1142 | f 375 315 377 1143 | f 316 354 374 1144 | f 316 374 378 1145 | f 375 355 317 1146 | f 375 317 379 1147 | f 354 356 372 1148 | f 354 372 374 1149 | f 373 357 355 1150 | f 373 355 375 1151 | f 356 358 366 1152 | f 356 366 372 1153 | f 367 359 357 1154 | f 367 357 373 1155 | f 358 360 364 1156 | f 358 364 366 1157 | f 365 361 359 1158 | f 365 359 367 1159 | f 290 292 364 1160 | f 290 364 360 1161 | f 365 293 291 1162 | f 365 291 361 1163 | f 74 360 358 1164 | f 74 358 302 1165 | f 359 361 74 1166 | f 359 74 302 1167 | f 284 286 288 1168 | f 284 288 290 1169 | f 289 287 285 1170 | f 289 285 291 1171 | f 284 290 360 1172 | f 284 360 74 1173 | f 361 291 285 1174 | f 361 285 74 1175 | f 73 284 74 1176 | f 74 285 73 1177 | f 294 296 310 1178 | f 294 310 362 1179 | f 311 297 295 1180 | f 311 295 363 1181 | f 310 312 368 1182 | f 310 368 362 1183 | f 369 313 311 1184 | f 369 311 363 1185 | f 312 382 370 1186 | f 312 370 368 1187 | f 371 383 313 1188 | f 371 313 369 1189 | f 314 376 370 1190 | f 314 370 382 1191 | f 371 377 315 1192 | f 371 315 383 1193 | f 348 350 386 1194 | f 348 386 384 1195 | f 387 351 349 1196 | f 387 349 385 1197 | f 318 384 386 1198 | f 318 386 320 1199 | f 387 385 319 1200 | f 387 319 321 1201 | f 298 300 384 1202 | f 298 384 318 1203 | f 385 301 299 1204 | f 385 299 319 1205 | f 300 344 342 1206 | f 300 342 384 1207 | f 343 345 301 1208 | f 343 301 385 1209 | f 342 348 384 1210 | f 385 349 343 1211 | f 300 346 344 1212 | f 345 347 301 1213 | f 314 322 380 1214 | f 314 380 378 1215 | f 381 323 315 1216 | f 381 315 379 1217 | f 316 378 380 1218 | f 316 380 324 1219 | f 381 379 317 1220 | f 381 317 325 1221 | f 320 386 380 1222 | f 320 380 322 1223 | f 381 387 321 1224 | f 381 321 323 1225 | f 350 352 380 1226 | f 350 380 386 1227 | f 381 353 351 1228 | f 381 351 387 1229 | f 324 380 352 1230 | f 353 381 325 1231 | f 400 388 414 1232 | f 400 414 402 1233 | f 415 389 401 1234 | f 415 401 403 1235 | f 400 402 404 1236 | f 400 404 398 1237 | f 405 403 401 1238 | f 405 401 399 1239 | f 398 404 406 1240 | f 398 406 396 1241 | f 407 405 399 1242 | f 407 399 397 1243 | f 396 406 408 1244 | f 396 408 394 1245 | f 409 407 397 1246 | f 409 397 395 1247 | f 394 408 410 1248 | f 394 410 392 1249 | f 411 409 395 1250 | f 411 395 393 1251 | f 392 410 412 1252 | f 392 412 390 1253 | f 413 411 393 1254 | f 413 393 391 1255 | f 410 420 418 1256 | f 410 418 412 1257 | f 419 421 411 1258 | f 419 411 413 1259 | f 408 422 420 1260 | f 408 420 410 1261 | f 421 423 409 1262 | f 421 409 411 1263 | f 406 424 422 1264 | f 406 422 408 1265 | f 423 425 407 1266 | f 423 407 409 1267 | f 404 426 424 1268 | f 404 424 406 1269 | f 425 427 405 1270 | f 425 405 407 1271 | f 402 428 426 1272 | f 402 426 404 1273 | f 427 429 403 1274 | f 427 403 405 1275 | f 402 414 416 1276 | f 402 416 428 1277 | f 417 415 403 1278 | f 417 403 429 1279 | f 318 320 444 1280 | f 318 444 442 1281 | f 445 321 319 1282 | f 445 319 443 1283 | f 320 390 412 1284 | f 320 412 444 1285 | f 413 391 321 1286 | f 413 321 445 1287 | f 310 318 442 1288 | f 310 442 312 1289 | f 443 319 311 1290 | f 443 311 313 1291 | f 382 430 414 1292 | f 382 414 388 1293 | f 415 431 383 1294 | f 415 383 389 1295 | f 412 418 440 1296 | f 412 440 444 1297 | f 441 419 413 1298 | f 441 413 445 1299 | f 438 446 444 1300 | f 438 444 440 1301 | f 445 447 439 1302 | f 445 439 441 1303 | f 434 446 438 1304 | f 434 438 436 1305 | f 439 447 435 1306 | f 439 435 437 1307 | f 432 448 446 1308 | f 432 446 434 1309 | f 447 449 433 1310 | f 447 433 435 1311 | f 430 448 432 1312 | f 430 432 450 1313 | f 433 449 431 1314 | f 433 431 451 1315 | f 414 430 450 1316 | f 414 450 416 1317 | f 451 431 415 1318 | f 451 415 417 1319 | f 312 448 430 1320 | f 312 430 382 1321 | f 431 449 313 1322 | f 431 313 383 1323 | f 312 442 446 1324 | f 312 446 448 1325 | f 447 443 313 1326 | f 447 313 449 1327 | f 442 444 446 1328 | f 447 445 443 1329 | f 416 450 452 1330 | f 416 452 476 1331 | f 453 451 417 1332 | f 453 417 477 1333 | f 450 432 462 1334 | f 450 462 452 1335 | f 463 433 451 1336 | f 463 451 453 1337 | f 432 434 460 1338 | f 432 460 462 1339 | f 461 435 433 1340 | f 461 433 463 1341 | f 434 436 458 1342 | f 434 458 460 1343 | f 459 437 435 1344 | f 459 435 461 1345 | f 436 438 456 1346 | f 436 456 458 1347 | f 457 439 437 1348 | f 457 437 459 1349 | f 438 440 454 1350 | f 438 454 456 1351 | f 455 441 439 1352 | f 455 439 457 1353 | f 440 418 474 1354 | f 440 474 454 1355 | f 475 419 441 1356 | f 475 441 455 1357 | f 428 416 476 1358 | f 428 476 464 1359 | f 477 417 429 1360 | f 477 429 465 1361 | f 426 428 464 1362 | f 426 464 466 1363 | f 465 429 427 1364 | f 465 427 467 1365 | f 424 426 466 1366 | f 424 466 468 1367 | f 467 427 425 1368 | f 467 425 469 1369 | f 422 424 468 1370 | f 422 468 470 1371 | f 469 425 423 1372 | f 469 423 471 1373 | f 420 422 470 1374 | f 420 470 472 1375 | f 471 423 421 1376 | f 471 421 473 1377 | f 418 420 472 1378 | f 418 472 474 1379 | f 473 421 419 1380 | f 473 419 475 1381 | f 458 456 480 1382 | f 458 480 478 1383 | f 481 457 459 1384 | f 481 459 479 1385 | f 478 480 482 1386 | f 478 482 484 1387 | f 483 481 479 1388 | f 483 479 485 1389 | f 484 482 488 1390 | f 484 488 486 1391 | f 489 483 485 1392 | f 489 485 487 1393 | f 486 488 490 1394 | f 486 490 492 1395 | f 491 489 487 1396 | f 491 487 493 1397 | f 464 476 486 1398 | f 464 486 492 1399 | f 487 477 465 1400 | f 487 465 493 1401 | f 452 484 486 1402 | f 452 486 476 1403 | f 487 485 453 1404 | f 487 453 477 1405 | f 452 462 478 1406 | f 452 478 484 1407 | f 479 463 453 1408 | f 479 453 485 1409 | f 458 478 462 1410 | f 458 462 460 1411 | f 463 479 459 1412 | f 463 459 461 1413 | f 454 474 480 1414 | f 454 480 456 1415 | f 481 475 455 1416 | f 481 455 457 1417 | f 472 482 480 1418 | f 472 480 474 1419 | f 481 483 473 1420 | f 481 473 475 1421 | f 470 488 482 1422 | f 470 482 472 1423 | f 483 489 471 1424 | f 483 471 473 1425 | f 468 490 488 1426 | f 468 488 470 1427 | f 489 491 469 1428 | f 489 469 471 1429 | f 466 492 490 1430 | f 466 490 468 1431 | f 491 493 467 1432 | f 491 467 469 1433 | f 464 492 466 1434 | f 467 493 465 1435 | f 392 390 504 1436 | f 392 504 502 1437 | f 505 391 393 1438 | f 505 393 503 1439 | f 394 392 502 1440 | f 394 502 500 1441 | f 503 393 395 1442 | f 503 395 501 1443 | f 396 394 500 1444 | f 396 500 498 1445 | f 501 395 397 1446 | f 501 397 499 1447 | f 398 396 498 1448 | f 398 498 496 1449 | f 499 397 399 1450 | f 499 399 497 1451 | f 400 398 496 1452 | f 400 496 494 1453 | f 497 399 401 1454 | f 497 401 495 1455 | f 388 400 494 1456 | f 388 494 506 1457 | f 495 401 389 1458 | f 495 389 507 1459 | f 494 502 504 1460 | f 494 504 506 1461 | f 505 503 495 1462 | f 505 495 507 1463 | f 494 496 500 1464 | f 494 500 502 1465 | f 501 497 495 1466 | f 501 495 503 1467 | f 496 498 500 1468 | f 501 499 497 1469 | f 314 382 388 1470 | f 314 388 506 1471 | f 389 383 315 1472 | f 389 315 507 1473 | f 314 506 504 1474 | f 314 504 322 1475 | f 505 507 315 1476 | f 505 315 323 1477 | f 320 322 504 1478 | f 320 504 390 1479 | f 505 323 321 1480 | f 505 321 391 1481 | -------------------------------------------------------------------------------- /examples/obj-model.php: -------------------------------------------------------------------------------- 1 | load($modelName); 30 | echo $obj, PHP_EOL; 31 | 32 | $verticesObjects = $obj->getVertices(); 33 | $vertices = []; 34 | foreach($verticesObjects as $vertexObject) { 35 | $vertices[] = $vertexObject->x; 36 | $vertices[] = $vertexObject->y; 37 | $vertices[] = $vertexObject->z; 38 | } 39 | 40 | $indices = $obj->getVertexFaces(); 41 | $indices = array_map(function($index) { return $index - 1; }, $indices); 42 | 43 | $normalObjects = $obj->getVertexNormals(); 44 | $normals = []; 45 | foreach($normalObjects as $index => $normalObject) { 46 | if(!($normalObject instanceof Vector)) { 47 | echo "INDEX: $index\n"; 48 | var_dump($normalObject); 49 | } 50 | else { 51 | $normals[] = $normalObject->x; 52 | $normals[] = $normalObject->y; 53 | $normals[] = $normalObject->z; 54 | } 55 | } 56 | 57 | $vertexSource = file_get_contents('shaders/basic_lighting.vs'); 58 | $fragmentSource = file_get_contents('shaders/basic_lighting.frag'); 59 | 60 | $vertexShader = glCreateShader(GL_VERTEX_SHADER); 61 | glShaderSource($vertexShader, 1, $vertexSource, NULL); 62 | glCompileShader($vertexShader); 63 | 64 | $fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); 65 | glShaderSource($fragmentShader, 1, $fragmentSource, NULL); 66 | glCompileShader($fragmentShader); 67 | 68 | $shaderProgram = glCreateProgram(); 69 | glAttachShader($shaderProgram, $vertexShader); 70 | glAttachShader($shaderProgram, $fragmentShader); 71 | glLinkProgram($shaderProgram); 72 | 73 | glUseProgram($shaderProgram); 74 | $viewLoc = glGetUniformLocation($shaderProgram, "view"); 75 | $modelLoc = glGetUniformLocation($shaderProgram, "model"); 76 | $projLoc = glGetUniformLocation($shaderProgram, "projection"); 77 | 78 | $position = new Vector(0, 0, 10); 79 | $lampShader = null; 80 | $lightVAO = null; 81 | $lightPos = null; 82 | 83 | $lightPos = new Vector(0, 10, 10.0); 84 | $objectColorLoc = glGetUniformLocation($shaderProgram, "objectColor"); 85 | $lightColorLoc = glGetUniformLocation($shaderProgram, "lightColor"); 86 | $lightPosLoc = glGetUniformLocation($shaderProgram, "lightPos"); 87 | $viewPosLoc = glGetUniformLocation($shaderProgram, "viewPos"); 88 | glUniform3f($objectColorLoc, 1.0, 0.5, 0.31); 89 | glUniform3f($lightColorLoc, 1.0, 1.0, 1.0); 90 | glUniform3f($lightPosLoc, $lightPos->x, $lightPos->y, $lightPos->z); 91 | glUniform3f($viewPosLoc, $position->x, $position->y, $position->z); 92 | 93 | $view = Transform::lookAt($position, new Vector(0, 0, 0), new Vector(0,1,0)); 94 | $proj = Transform::perspective(45, (float)800/(float)600, 0.1, 100); 95 | 96 | $model = new Matrix(); 97 | //$model = \glm\rotate($model, 40, new Vector(1, 0, 0)); 98 | glUniformMatrix4fv($modelLoc, 1, GL_FALSE, $model->toRowVector()); 99 | glUniformMatrix4fv($viewLoc, 1, GL_FALSE, $view->toRowVector()); 100 | glUniformMatrix4fv($projLoc, 1, GL_FALSE, $proj->toRowVector()); 101 | 102 | glGenVertexArrays(1, $vaos); 103 | $vao = $vaos[0]; 104 | 105 | glBindVertexArray($vao); 106 | 107 | glGenBuffers(1, $vbos); $vbo = $vbos[0]; 108 | glBindBuffer(GL_ARRAY_BUFFER, $vbo); 109 | glBufferData(GL_ARRAY_BUFFER, count($vertices) * 4, $vertices, GL_STATIC_DRAW); 110 | 111 | glGenBuffers(1, $vbo_normals); $vbo_normal = $vbo_normals[0]; 112 | glBindBuffer(GL_ARRAY_BUFFER, $vbo_normal); 113 | glBufferData(GL_ARRAY_BUFFER, count($normals) * 4, $normals, GL_STATIC_DRAW); 114 | 115 | glGenBuffers(1, $ebos); $ebo = $ebos[0]; 116 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, $ebo); 117 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, count($indices) * 4, $indices, GL_STATIC_DRAW); 118 | 119 | // Vertex attribute 120 | glEnableVertexAttribArray(0); 121 | glBindBuffer(GL_ARRAY_BUFFER, $vbo); 122 | glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 123 | 124 | // Normal attribute 125 | glEnableVertexAttribArray(1); 126 | glBindBuffer(GL_ARRAY_BUFFER, $vbo_normal); 127 | glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0); 128 | 129 | glBindVertexArray(0); 130 | 131 | // Then, we set the light's VAO (VBO stays the same. After all, the vertices are the same for the light object (also a 3D cube)) 132 | 133 | $lampShader = new Shader\Program(); 134 | $lampShader->add(new Shader\Vertex('shaders/lamp.vs')); 135 | $lampShader->add(new Shader\Fragment('shaders/lamp.frag')); 136 | $lampShader->compile(); 137 | $lampShader->link(); 138 | 139 | 140 | glGenVertexArrays(1, $lightVAOS); $lightVAO = $lightVAOS[0]; 141 | glBindVertexArray($lightVAO); 142 | // We only need to bind to the VBO (to link it with glVertexAttribPointer), no need to fill it; the VBO's data already contains all we need. 143 | $lightVertices2 = [ 144 | (new Vector(-0.1, -0.1, -0.1, 0.0)), 145 | (new Vector( 0.1, -0.1, -0.1, 0.0)), 146 | (new Vector( 0.1, 0.1, -0.1, 0.0)), 147 | (new Vector(-0.1, 0.1, -0.1, 0.0)), 148 | (new Vector(-0.1, -0.1, 0.1, 0.0)), 149 | (new Vector( 0.1, -0.1, 0.1, 0.0)), 150 | (new Vector( 0.1, 0.1, 0.1, 0.0)), 151 | (new Vector(-0.1, 0.1, 0.1, 0.0)), 152 | ]; 153 | $lightVertices = []; 154 | foreach($lightVertices2 as $l) { 155 | $lightVertices[] = $l->x; 156 | $lightVertices[] = $l->y; 157 | $lightVertices[] = $l->z; 158 | } 159 | 160 | glGenBuffers(1, $vbo_lights); $vbo_light = $vbo_lights[0]; 161 | glBindBuffer(GL_ARRAY_BUFFER, $vbo_light); 162 | glBufferData(GL_ARRAY_BUFFER, count($lightVertices) * 4, $lightVertices, GL_STATIC_DRAW); 163 | // Set the vertex attributes (only position data for the lamp)) 164 | glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * 4, 0); // Note that we skip over the normal vectors 165 | glEnableVertexAttribArray(0); 166 | glBindVertexArray(0); 167 | glPolygonMode(GL_FRONT_AND_BACK, $line ? GL_LINE : GL_FILL); 168 | 169 | $event = new SDL_Event; 170 | while(true) { 171 | glClearColor(.2, .3, .3, 1); 172 | glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 173 | 174 | glUseProgram($shaderProgram); 175 | 176 | glBindVertexArray($vao); 177 | $numFaces = count($indices); 178 | glDrawElements(GL_TRIANGLES, $numFaces, GL_UNSIGNED_INT, null); 179 | glBindVertexArray(0); 180 | 181 | $lampShader->Use(); 182 | // Get location objects for the matrices on the lamp shader (these could be different on a different shader) 183 | $modelLoc = glGetUniformLocation($lampShader->getId(), "model"); 184 | $viewLoc = glGetUniformLocation($lampShader->getId(), "view"); 185 | $projLoc = glGetUniformLocation($lampShader->getId(), "projection"); 186 | // Set matrices 187 | glUniformMatrix4fv($viewLoc, 1, GL_FALSE, $view->toRowVector()); 188 | glUniformMatrix4fv($projLoc, 1, GL_FALSE, $proj->toRowVector()); 189 | $model = new Matrix(); 190 | $model = Transform::translate($model, $lightPos); 191 | glUniformMatrix4fv($modelLoc, 1, GL_FALSE, $model->toRowVector()); 192 | // Draw the light object (using light's vertex attributes) 193 | glBindVertexArray($lightVAO); 194 | glDrawArrays(GL_TRIANGLES, 0, 36); //8*4 195 | glBindVertexArray(0); 196 | SDL_GL_SwapWindow($window); 197 | SDL_Delay(10); 198 | SDL_PollEvent($event); 199 | if($event->type == SDL_KEYDOWN) { 200 | $line = !$line; 201 | 202 | glPolygonMode(GL_FRONT_AND_BACK, $line ? GL_LINE : GL_FILL); 203 | } 204 | } 205 | 206 | glEnable(GL_BLEND); 207 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 208 | glEnable(GL_DEPTH_TEST); 209 | 210 | -------------------------------------------------------------------------------- /examples/rectangle.php: -------------------------------------------------------------------------------- 1 | type == SDL_KEYDOWN) break; 89 | } 90 | 91 | SDL_DestroyWindow($window); 92 | 93 | -------------------------------------------------------------------------------- /examples/rotate.php: -------------------------------------------------------------------------------- 1 | add(new Shader\Vertex("shaders/transformations.vert")); 32 | $shaderProgram->add(new Shader\Fragment("shaders/transformations.frag")); 33 | $shaderProgram->compile(); 34 | $shaderProgram->link(); 35 | $shaderProgram->use(); 36 | 37 | // Set up vertex data (and buffer(s)) and attribute pointers 38 | $vertices = [ 39 | // Positions // Colors // Texture Coords 40 | 0.5, 0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, // Top Right 41 | 0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, // Bottom Right 42 | -0.5, -0.5, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, // Bottom Left 43 | -0.5, 0.5, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0 // Top Left 44 | ]; 45 | $indices = [ // Note that we start from 0! 46 | 0, 1, 3, // First Triangle 47 | 1, 2, 3 // Second Triangle 48 | ]; 49 | glGenVertexArrays(1, $VAOS); $VAO=$VAOS[0]; 50 | glGenBuffers(1, $VBOS); $VBO=$VBOS[0]; 51 | glGenBuffers(1, $EBOS); $EBO=$EBOS[0]; 52 | 53 | glBindVertexArray($VAO); 54 | 55 | glBindBuffer(GL_ARRAY_BUFFER, $VBO); 56 | glBufferData(GL_ARRAY_BUFFER, sizeof($vertices) * 4, $vertices, GL_STATIC_DRAW); 57 | 58 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, $EBO); 59 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof($indices) * 4, $indices, GL_STATIC_DRAW); 60 | 61 | // Position attribute 62 | glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * 4, 0); 63 | glEnableVertexAttribArray(0); 64 | // Color attribute 65 | glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * 4, (3 * 4)); 66 | glEnableVertexAttribArray(1); 67 | // TexCoord attribute 68 | glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * 4, (6 * 4)); 69 | glEnableVertexAttribArray(2); 70 | 71 | glBindVertexArray(0); // Unbind VAO 72 | 73 | $imageLoader = new ImageLoader; 74 | 75 | // Load and create a texture 76 | // ==================== 77 | // Texture 1 78 | // ==================== 79 | $textures =[]; 80 | glGenTextures(1, $textures); $texture1=$textures[0]; 81 | glBindTexture(GL_TEXTURE_2D, $texture1); // All upcoming GL_TEXTURE_2D operations now have effect on our texture object 82 | // Set our texture parameters 83 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture wrapping to GL_REPEAT 84 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 85 | // Set texture filtering 86 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 87 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 88 | // Load, create texture and generate mipmaps 89 | $image = $imageLoader->load("textures/container.jpg", $width, $height); 90 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, $width, $height, 0, GL_RGBA, GL_UNSIGNED_BYTE, $image); 91 | glGenerateMipmap(GL_TEXTURE_2D); 92 | glBindTexture(GL_TEXTURE_2D, 0); // Unbind texture when done, so we won't accidentily mess up our texture. 93 | // =================== 94 | // Texture 2 95 | // =================== 96 | $textures2 = []; 97 | glGenTextures(1, $textures2); $texture2=$textures2[0]; 98 | glBindTexture(GL_TEXTURE_2D, $texture2); 99 | // Set our texture parameters 100 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 101 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 102 | // Set texture filtering 103 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 104 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 105 | // Load, create texture and generate mipmaps 106 | $image = $imageLoader->load("textures/awesomeface.png", $width, $height); 107 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, $width, $height, 0, GL_BGRA, GL_UNSIGNED_BYTE, $image); 108 | glGenerateMipmap(GL_TEXTURE_2D); 109 | glBindTexture(GL_TEXTURE_2D, 0); 110 | 111 | $event = new SDL_Event; 112 | while(true) { 113 | // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions 114 | 115 | // Render 116 | // Clear the colorbuffer 117 | glClearColor(0.2, 0.3, 0.3, 1.0); 118 | glClear(GL_COLOR_BUFFER_BIT); 119 | 120 | // Bind Textures using texture units 121 | glActiveTexture(GL_TEXTURE0); 122 | glBindTexture(GL_TEXTURE_2D, $texture1); 123 | glUniform1i(glGetUniformLocation($shaderProgram->getId(), "ourTexture1"), 0); 124 | glActiveTexture(GL_TEXTURE1); 125 | glBindTexture(GL_TEXTURE_2D, $texture2); 126 | glUniform1i(glGetUniformLocation($shaderProgram->getId(), "ourTexture2"), 1); 127 | 128 | // Activate shader 129 | $shaderProgram->Use(); 130 | 131 | // Create transformations 132 | static $a = 0; 133 | $a -= 0.01; 134 | $transform = new Matrix(); 135 | $transform = Transform::translate($transform, new Vector(0.5, -0.5, 0.0)); 136 | $transform = Transform::rotate($transform, ($a * 50.0), new Vector(0.0, 0.0, 1.0)); 137 | 138 | // Get matrix's uniform location and set matrix 139 | $transformLoc = glGetUniformLocation($shaderProgram->getId(), "transform"); 140 | glUniformMatrix4fv($transformLoc, 1, GL_FALSE, $transform->toRowVector()); 141 | 142 | // Draw container 143 | glBindVertexArray($VAO); 144 | glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, null); 145 | glBindVertexArray(0); 146 | 147 | // Swap the screen buffers 148 | SDL_GL_SwapWindow($window); 149 | SDL_PollEvent($event); 150 | if($event->type == SDL_KEYDOWN) break; 151 | 152 | SDL_Delay(5); 153 | } 154 | // Properly de-allocate all resources once they've outlived their purpose 155 | glDeleteVertexArrays(1, $VAO); 156 | glDeleteBuffers(1, $VBO); 157 | glDeleteBuffers(1, $EBO); 158 | 159 | -------------------------------------------------------------------------------- /examples/shader-effect.php: -------------------------------------------------------------------------------- 1 | load("textures/sample.png", $width, $height); 121 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, $width, $height, 0, GL_RGBA, GL_UNSIGNED_BYTE, $image); 122 | glUniform1i(glGetUniformLocation($shaderProgram, "texKitten"), 0); 123 | 124 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 125 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 126 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 127 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 128 | 129 | 130 | glActiveTexture(GL_TEXTURE1); 131 | glBindTexture(GL_TEXTURE_2D, $textures[1]); 132 | $image = $imageLoader->load("textures/sample2.png", $width, $height); 133 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, $width, $height, 0, GL_RGBA, GL_UNSIGNED_BYTE, $image); 134 | glUniform1i(glGetUniformLocation($shaderProgram, "texPuppy"), 1); 135 | 136 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 137 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 138 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 139 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 140 | 141 | $a = 0.0; 142 | 143 | $start = microtime(true); 144 | 145 | $event = new SDL_Event; 146 | 147 | $quit = false; 148 | while (!$quit) { 149 | // Clear the screen to black 150 | glClearColor(0.0, 0.0, 0.0, 1.0); 151 | glClear(GL_COLOR_BUFFER_BIT); 152 | 153 | $a += 0.05; 154 | 155 | // Draw a rectangle from the 2 triangles using 6 indices 156 | glUniform1f(glGetUniformLocation($shaderProgram, "time"), $a); 157 | glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, null); 158 | 159 | // Swap buffers 160 | SDL_GL_SwapWindow($window); 161 | while (SDL_PollEvent($event)) { 162 | if ($event->type == SDL_KEYDOWN) $quit = true; 163 | } 164 | 165 | SDL_Delay(10); 166 | } 167 | 168 | 169 | glDeleteTextures(2, $textures); 170 | 171 | glDeleteProgram($shaderProgram); 172 | glDeleteShader($fragmentShader); 173 | glDeleteShader($vertexShader); 174 | 175 | glDeleteBuffers(1, $ebo); 176 | glDeleteBuffers(1, $vbo); 177 | 178 | glDeleteVertexArrays(1, $vao); 179 | -------------------------------------------------------------------------------- /examples/shaders/basic_lighting.frag: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | out vec4 color; 4 | 5 | in vec3 FragPos; 6 | in vec3 Normal; 7 | 8 | uniform vec3 lightPos; 9 | uniform vec3 viewPos; 10 | uniform vec3 lightColor; 11 | uniform vec3 objectColor; 12 | 13 | void main() 14 | { 15 | vec3 objectColor = vec3(1, 0.5, 0.31); 16 | vec3 lightColor = vec3(1, 1, 1); 17 | vec3 lightPos = vec3(1.2, 1, 2); 18 | vec3 viewPos = vec3(0,0,3); 19 | 20 | // Ambient 21 | float ambientStrength = 0.1f; 22 | vec3 ambient = ambientStrength * lightColor; 23 | 24 | // Diffuse 25 | vec3 norm = normalize(Normal); 26 | vec3 lightDir = normalize(lightPos - FragPos); 27 | float diff = max(dot(norm, lightDir), 0.0); 28 | vec3 diffuse = diff * lightColor; 29 | 30 | // Specular 31 | float specularStrength = 0.5f; 32 | vec3 viewDir = normalize(viewPos - FragPos); 33 | vec3 reflectDir = reflect(-lightDir, norm); 34 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); 35 | vec3 specular = specularStrength * spec * lightColor; 36 | 37 | vec3 result = (ambient + diffuse + specular) * objectColor; 38 | color = vec4(result, 1.0f); 39 | } 40 | -------------------------------------------------------------------------------- /examples/shaders/basic_lighting.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | in vec3 position; 4 | in vec3 normal; 5 | 6 | out vec3 Normal; 7 | out vec3 FragPos; 8 | 9 | uniform mat4 model; 10 | uniform mat4 view; 11 | uniform mat4 projection; 12 | 13 | void main() 14 | { 15 | gl_Position = projection * view * model * vec4(position, 1.0f); 16 | FragPos = vec3(model * vec4(position, 1.0f)); 17 | Normal = mat3(transpose(inverse(model))) * normal; 18 | } 19 | -------------------------------------------------------------------------------- /examples/shaders/camera.frag: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | in vec3 ourColor; 3 | in vec2 TexCoord; 4 | 5 | out vec4 color; 6 | 7 | // Texture samplers 8 | uniform sampler2D ourTexture1; 9 | uniform sampler2D ourTexture2; 10 | 11 | void main() 12 | { 13 | // Linearly interpolate between both textures (second texture is only slightly combined) 14 | color = mix(texture(ourTexture1, TexCoord), texture(ourTexture2, TexCoord), 0.2); 15 | } 16 | -------------------------------------------------------------------------------- /examples/shaders/camera.vert: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 position; 3 | layout (location = 2) in vec2 texCoord; 4 | 5 | out vec2 TexCoord; 6 | 7 | uniform mat4 model; 8 | uniform mat4 view; 9 | uniform mat4 projection; 10 | 11 | void main() 12 | { 13 | gl_Position = projection * view * model * vec4(position, 1.0f); 14 | TexCoord = vec2(texCoord.x, 1.0 - texCoord.y); 15 | } 16 | -------------------------------------------------------------------------------- /examples/shaders/geometry-shader.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec3 fColor; 5 | 6 | void main() 7 | { 8 | FragColor = vec4(fColor, 1.0); 9 | } 10 | -------------------------------------------------------------------------------- /examples/shaders/geometry-shader.gs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (points) in; 3 | layout (triangle_strip, max_vertices = 5) out; 4 | 5 | in VS_OUT { 6 | vec3 color; 7 | } gs_in[]; 8 | 9 | out vec3 fColor; 10 | 11 | void build_house(vec4 position) 12 | { 13 | fColor = gs_in[0].color; // gs_in[0] since there's only one input vertex 14 | gl_Position = position + vec4(-0.2, -0.2, 0.0, 0.0); // 1:bottom-left 15 | EmitVertex(); 16 | gl_Position = position + vec4( 0.2, -0.2, 0.0, 0.0); // 2:bottom-right 17 | EmitVertex(); 18 | gl_Position = position + vec4(-0.2, 0.2, 0.0, 0.0); // 3:top-left 19 | EmitVertex(); 20 | gl_Position = position + vec4( 0.2, 0.2, 0.0, 0.0); // 4:top-right 21 | EmitVertex(); 22 | gl_Position = position + vec4( 0.0, 0.4, 0.0, 0.0); // 5:top 23 | fColor = vec3(1.0, 1.0, 1.0); 24 | EmitVertex(); 25 | EndPrimitive(); 26 | } 27 | 28 | void main() { 29 | build_house(gl_in[0].gl_Position); 30 | } 31 | -------------------------------------------------------------------------------- /examples/shaders/geometry-shader.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec2 aPos; 3 | layout (location = 1) in vec3 aColor; 4 | 5 | out VS_OUT { 6 | vec3 color; 7 | } vs_out; 8 | 9 | void main() 10 | { 11 | vs_out.color = aColor; 12 | gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0); 13 | } 14 | -------------------------------------------------------------------------------- /examples/shaders/lamp.frag: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 color; 3 | 4 | void main() 5 | { 6 | color = vec4(1.0f); // Set all 4 vector values to 1 7 | } 8 | -------------------------------------------------------------------------------- /examples/shaders/lamp.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 position; 3 | 4 | uniform mat4 model; 5 | uniform mat4 view; 6 | uniform mat4 projection; 7 | 8 | void main() 9 | { 10 | gl_Position = projection * view * model * .2 * vec4(position, 1.0f); 11 | } 12 | 13 | -------------------------------------------------------------------------------- /examples/shaders/transformations.frag: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | in vec3 ourColor; 3 | in vec2 TexCoord; 4 | 5 | out vec4 color; 6 | 7 | // Texture samplers 8 | uniform sampler2D ourTexture1; 9 | uniform sampler2D ourTexture2; 10 | 11 | void main() 12 | { 13 | // Linearly interpolate between both textures (second texture is only slightly combined) 14 | color = mix(texture(ourTexture1, TexCoord), texture(ourTexture2, TexCoord), 0.2); 15 | } 16 | -------------------------------------------------------------------------------- /examples/shaders/transformations.vert: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 position; 3 | layout (location = 1) in vec3 color; 4 | layout (location = 2) in vec2 texCoord; 5 | 6 | out vec3 ourColor; 7 | out vec2 TexCoord; 8 | 9 | uniform mat4 transform; 10 | 11 | void main() 12 | { 13 | gl_Position = transform * vec4(position, 1.0f); 14 | ourColor = color; 15 | TexCoord = vec2(texCoord.x, 1.0 - texCoord.y); 16 | } 17 | -------------------------------------------------------------------------------- /examples/textures/awesomeface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ponup/php-opengl/438798d5f0a5347a59d13252611556792cc2a1b8/examples/textures/awesomeface.png -------------------------------------------------------------------------------- /examples/textures/container.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ponup/php-opengl/438798d5f0a5347a59d13252611556792cc2a1b8/examples/textures/container.jpg -------------------------------------------------------------------------------- /examples/textures/sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ponup/php-opengl/438798d5f0a5347a59d13252611556792cc2a1b8/examples/textures/sample.png -------------------------------------------------------------------------------- /examples/textures/sample2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ponup/php-opengl/438798d5f0a5347a59d13252611556792cc2a1b8/examples/textures/sample2.png -------------------------------------------------------------------------------- /opengl-camera-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ponup/php-opengl/438798d5f0a5347a59d13252611556792cc2a1b8/opengl-camera-demo.gif -------------------------------------------------------------------------------- /opengl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | -------------------------------------------------------------------------------- /package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | opengl 4 | pecl.php.net 5 | OpenGL (3D graphics library) for PHP 6 | This extension allows you to develop 3D multimedia applications with PHP using the complete OpenGL library API. 7 | 8 | Santiago Lizardo 9 | santiagolizardo 10 | santiagolizardo@php.net 11 | yes 12 | 13 | 2019-09-02 14 | 15 | 16 | 0.9.10 17 | 0.9.10 18 | 19 | 20 | beta 21 | beta 22 | 23 | PHP License 24 | 25 | - Fix memory leaks. 26 | - Improve build files. 27 | - Remove deprecated code. 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 7.3.0 50 | 51 | 52 | 1.9 53 | 54 | 55 | sdl 56 | 57 | 58 | 59 | opengl 60 | 61 | 62 | 63 | 64 | 65 | 2018-09-22 66 | 67 | 68 | 0.9.0 69 | 0.9.0 70 | 71 | 72 | beta 73 | beta 74 | 75 | 76 | - Better PHP7.2 support. 77 | - Example scripts included in the main extension package. 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /php-sdl.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:11 2 | 3 | ARG TARGET_PHP_VERSION=8.1 4 | 5 | RUN apt-get update 6 | RUN apt-get install -y make build-essential wget 7 | RUN apt-get install -y lsb-release apt-transport-https ca-certificates 8 | RUN wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg 9 | RUN echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | tee /etc/apt/sources.list.d/php.list 10 | RUN apt-get update 11 | RUN apt-get install -y php${TARGET_PHP_VERSION}-dev 12 | RUN apt-get install -y libsdl2-dev 13 | RUN apt-get install -y xvfb 14 | COPY . /opt/php-sdl 15 | WORKDIR /opt/php-sdl 16 | RUN phpize 17 | RUN ./configure 18 | RUN make 19 | RUN make install 20 | RUN echo "extension=sdl.so" >> /etc/php/${TARGET_PHP_VERSION}/cli/php.ini 21 | 22 | ENTRYPOINT ["/opt/php-sdl/docker-entrypoint.sh"] 23 | 24 | -------------------------------------------------------------------------------- /php_convert.c: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 7 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2016 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.01 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_01.txt | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Santiago Lizardo | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | 20 | #ifdef PHP_WIN32 21 | #include 22 | #endif 23 | 24 | #include "php.h" 25 | #include "php_convert.h" 26 | 27 | void c_array_to_php_array(void *c_array, int num, zval *php_array, int type) { 28 | zval val; 29 | int i; 30 | 31 | for (i = 0; i < num; i++) { 32 | switch (type) { 33 | case C_INT_TO_PHP_LONG: 34 | ZVAL_LONG(&val, (int) ((int*) c_array)[i]); 35 | break; 36 | case C_UINT_TO_PHP_LONG: 37 | ZVAL_LONG(&val, (unsigned int) ((unsigned int*) c_array)[i]); 38 | break; 39 | case C_LONG_TO_PHP_LONG: 40 | ZVAL_LONG(&val, ((long*) c_array)[i]); 41 | break; 42 | case C_FLOAT_TO_PHP_DOUBLE: 43 | ZVAL_DOUBLE(&val, (float) ((float*) c_array)[i]); 44 | break; 45 | case C_DOUBLE_TO_PHP_DOUBLE: 46 | ZVAL_DOUBLE(&val, (double) ((double*) c_array)[i]); 47 | break; 48 | case C_BOOLEAN_TO_PHP_BOOLEAN: 49 | ZVAL_BOOL(&val, (unsigned char) ((unsigned char*) c_array)[i]); 50 | break; 51 | case C_CHAR_TO_PHP_LONG: 52 | ZVAL_LONG(&val, (char) ((char*) c_array)[i]); 53 | break; 54 | case C_USHORT_TO_PHP_LONG: 55 | ZVAL_LONG(&val, (unsigned short) ((unsigned short*) c_array)[i]); 56 | break; 57 | } 58 | zend_hash_next_index_insert(Z_ARRVAL_P(php_array), &val); 59 | } 60 | } 61 | 62 | void *php_array_to_c_array(zval *param, int type, int size, int *array_size) { 63 | zend_array *param_ht = HASH_OF(param); 64 | zval *cur = NULL; 65 | void *params; 66 | int i, tmp_size = zend_hash_num_elements(param_ht); 67 | 68 | params = (void *) emalloc(size * tmp_size); 69 | 70 | i = 0; 71 | 72 | ZEND_HASH_FOREACH_VAL(param_ht, cur) { 73 | if (Z_TYPE_P(cur) == IS_ARRAY) { 74 | int new_array_size; 75 | void *array = php_array_to_c_array(cur, type, size, &new_array_size); 76 | params = erealloc(params, (tmp_size + new_array_size) * size); 77 | memcpy(&((char*) params)[i * size], array, new_array_size * size); 78 | i += (new_array_size - 1); 79 | efree(array); 80 | } else { 81 | switch (type) { 82 | case TO_C_FLOAT: 83 | convert_to_double(cur); 84 | ((float*) params)[i] = (float) Z_DVAL_P(cur); 85 | break; 86 | case TO_C_DOUBLE: 87 | convert_to_double(cur); 88 | ((double*) params)[i] = Z_DVAL_P(cur); 89 | break; 90 | case TO_C_INT: 91 | convert_to_long(cur); 92 | ((int*) params)[i] = (int) Z_LVAL_P(cur); 93 | break; 94 | case TO_C_LONG: 95 | convert_to_long(cur); 96 | ((long*) params)[i] = Z_LVAL_P(cur); 97 | break; 98 | case TO_C_UCHAR: 99 | convert_to_long(cur); 100 | ((unsigned char*) params)[i] = (unsigned char) Z_LVAL_P(cur); 101 | break; 102 | case TO_C_SCHAR: 103 | convert_to_long(cur); 104 | ((signed char*) params)[i] = (signed char) Z_LVAL_P(cur); 105 | break; 106 | case TO_C_USHORT: 107 | convert_to_long(cur); 108 | ((unsigned short*) params)[i] = (unsigned short) Z_LVAL_P(cur); 109 | break; 110 | case TO_C_SHORT: 111 | convert_to_long(cur); 112 | ((short*) params)[i] = (short) Z_LVAL_P(cur); 113 | break; 114 | case TO_C_UINT: 115 | convert_to_long(cur); 116 | ((unsigned int*) params)[i] = (unsigned int) Z_LVAL_P(cur); 117 | break; 118 | case TO_C_STRING: 119 | convert_to_string(cur); 120 | ((char **) params)[i] = estrdup(Z_STRVAL_P(cur)); 121 | } 122 | } 123 | i++; 124 | } 125 | ZEND_HASH_FOREACH_END(); 126 | if (array_size != NULL) 127 | *array_size = i; 128 | return params; 129 | } 130 | 131 | int gl_pixel_size(GLenum format) { 132 | switch (format) { 133 | // case GL_COLOR_INDEX: 134 | case GL_RED: 135 | case GL_GREEN: 136 | case GL_BLUE: 137 | case GL_ALPHA: 138 | case GL_STENCIL_INDEX: 139 | case GL_DEPTH_COMPONENT: 140 | // case GL_LUMINANCE: 141 | return 1; 142 | 143 | // case GL_LUMINANCE_ALPHA: 144 | //: return 2; 145 | 146 | case GL_RGB: 147 | #ifdef GL_BGR_EXT 148 | case GL_BGR_EXT: 149 | #endif 150 | return 3; 151 | 152 | case GL_RGBA: 153 | #ifdef GL_BGRA_EXT 154 | case GL_BGRA_EXT: 155 | #endif 156 | #ifdef GL_ABGR_EXT 157 | case GL_ABGR_EXT: 158 | #endif 159 | return 4; 160 | case 1: 161 | case 2: 162 | case 3: 163 | case 4: 164 | return format; 165 | default: 166 | return -1; 167 | } 168 | } 169 | 170 | int gl_type_size(GLenum type) { 171 | switch (type) { 172 | case GL_BYTE: 173 | case GL_UNSIGNED_BYTE: 174 | return sizeof (GLbyte); 175 | 176 | case GL_SHORT: 177 | case GL_UNSIGNED_SHORT: 178 | return sizeof (GLshort); 179 | 180 | case GL_INT: 181 | case GL_UNSIGNED_INT: 182 | return sizeof (GLint); 183 | 184 | case GL_FLOAT: 185 | return sizeof (GLfloat); 186 | 187 | // case GL_BITMAP: 188 | // return sizeof (GLbitfield); 189 | 190 | default: 191 | return 1; 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /php_convert.h: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 7 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2016 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.01 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_01.txt | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Santiago Lizardo | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | #include "opengl.h" 20 | #include "php.h" 21 | 22 | #define C_INT_TO_PHP_LONG 1 23 | #define C_LONG_TO_PHP_LONG 2 24 | #define C_FLOAT_TO_PHP_DOUBLE 3 25 | #define C_DOUBLE_TO_PHP_DOUBLE 4 26 | #define C_BOOLEAN_TO_PHP_BOOLEAN 5 27 | #define C_CHAR_TO_PHP_LONG 6 28 | #define C_UINT_TO_PHP_LONG 7 29 | #define C_USHORT_TO_PHP_LONG 8 30 | 31 | #define TO_C_LONG 1 32 | #define TO_C_DOUBLE 2 33 | #define TO_C_INT 3 34 | #define TO_C_FLOAT 4 35 | #define TO_C_UCHAR 5 36 | #define TO_C_SCHAR 6 37 | #define TO_C_USHORT 7 38 | #define TO_C_SHORT 8 39 | #define TO_C_UINT 9 40 | #define TO_C_STRING 10 41 | #define TO_C_BYTE 11 42 | #define TO_C_UBYTE 12 43 | 44 | void c_array_to_php_array(void *c_array, int num, zval *php_array, int type); 45 | #define int_array_to_php_array(a,i,z) c_array_to_php_array(a,i,z,C_INT_TO_PHP_LONG) 46 | #define uint_array_to_php_array(a,i,z) c_array_to_php_array(a,i,z,C_UINT_TO_PHP_LONG) 47 | #define long_array_to_php_array(a,i,z) c_array_to_php_array(a,i,z,C_LONG_TO_PHP_LONG) 48 | #define float_array_to_php_array(a,i,z) c_array_to_php_array(a,i,z,C_FLOAT_TO_PHP_DOUBLE) 49 | #define boolean_array_to_php_array(a,i,z) c_array_to_php_array(a,i,z,C_BOOLEAN_TO_PHP_BOOLEAN) 50 | #define double_array_to_php_array(a,i,z) c_array_to_php_array(a,i,z,C_DOUBLE_TO_PHP_DOUBLE) 51 | #define ushort_array_to_php_array(a,i,z) c_array_to_php_array(a,i,z,C_USHORT_TO_PHP_LONG) 52 | #define char_array_to_php_array(a,i,z) c_array_to_php_array(a,i,z,C_CHAR_TO_PHP_LONG) 53 | 54 | void *php_array_to_c_array(zval *param, int type, int size, int *array_size); 55 | #define php_array_to_string_array(z) (char **)php_array_to_c_array(z,TO_C_STRING,sizeof(char *),NULL) 56 | #define php_array_to_byte_array(z) (char *)php_array_to_c_array(z,TO_C_BYTE,sizeof(char),NULL) 57 | #define php_array_to_ubyte_array(z) (unsigned char*)php_array_to_c_array(z,TO_C_UBYTE,sizeof(unsigned char),NULL) 58 | #define php_array_to_long_array(z) (long *)php_array_to_c_array(z,TO_C_LONG,sizeof(long),NULL) 59 | #define php_array_to_double_array(z) (double *)php_array_to_c_array(z,TO_C_DOUBLE,sizeof(double),NULL) 60 | #define php_array_to_int_array(z) (int *)php_array_to_c_array(z,TO_C_INT,sizeof(int),NULL) 61 | #define php_array_to_float_array(z) (float *)php_array_to_c_array(z,TO_C_FLOAT,sizeof(float),NULL) 62 | #define php_array_to_uchar_array(z) (unsigned char *)php_array_to_c_array(z,TO_C_UCHAR,sizeof(unsigned char),NULL) 63 | #define php_array_to_schar_array(z) (signed char *)php_array_to_c_array(z,TO_C_SCHAR,sizeof(signed char),NULL) 64 | #define php_array_to_ushort_array(z) (unsigned short *)php_array_to_c_array(z,TO_C_USHORT,sizeof(unsigned short),NULL) 65 | #define php_array_to_short_array(z) (short *)php_array_to_c_array(z,TO_C_SHORT,sizeof(short),NULL) 66 | #define php_array_to_uint_array(z) (unsigned int *)php_array_to_c_array(z,TO_C_UINT,sizeof(unsigned int),NULL) 67 | 68 | int gl_pixel_size(GLenum format); 69 | int gl_type_size(GLenum type); 70 | 71 | -------------------------------------------------------------------------------- /php_opengl.h: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 7 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2016 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.01 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_01.txt | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Santiago Lizardo | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | #ifndef PHP_OPENGL_H 20 | #define PHP_OPENGL_H 21 | 22 | #define PHP_OPENGL_VERSION "0.9.10" 23 | 24 | #include "php.h" 25 | #include "ext/standard/info.h" 26 | 27 | extern zend_module_entry opengl_module_entry; 28 | #define opengl_module_ptr &opengl_module_entry 29 | #define phpext_opengl_ptr opengl_module_ptr 30 | 31 | #ifdef ZTS 32 | #include "TSRM.h" 33 | #endif 34 | 35 | PHP_MINIT_FUNCTION(opengl); 36 | PHP_MINFO_FUNCTION(opengl); 37 | 38 | PHP_FUNCTION(glbindtexture); 39 | PHP_FUNCTION(glblendfunc); 40 | PHP_FUNCTION(glclear); 41 | PHP_FUNCTION(glclearcolor); 42 | PHP_FUNCTION(glcleardepth); 43 | PHP_FUNCTION(glclearstencil); 44 | PHP_FUNCTION(glcolormask); 45 | PHP_FUNCTION(glcopyteximage1d); 46 | PHP_FUNCTION(glcopytexsubimage1d); 47 | PHP_FUNCTION(glcullface); 48 | PHP_FUNCTION(gldeletetextures); 49 | PHP_FUNCTION(gldepthfunc); 50 | PHP_FUNCTION(gldepthmask); 51 | PHP_FUNCTION(gldepthrange); 52 | PHP_FUNCTION(gldisable); 53 | PHP_FUNCTION(gldrawarrays); 54 | PHP_FUNCTION(gldrawbuffer); 55 | PHP_FUNCTION(gldrawelements); 56 | PHP_FUNCTION(glenable); 57 | PHP_FUNCTION(glfinish); 58 | PHP_FUNCTION(glflush); 59 | PHP_FUNCTION(glfrontface); 60 | PHP_FUNCTION(glgentextures); 61 | PHP_FUNCTION(glgetbooleanv); 62 | PHP_FUNCTION(glgetdoublev); 63 | PHP_FUNCTION(glgeterror); 64 | PHP_FUNCTION(glgetfloatv); 65 | PHP_FUNCTION(glgetintegerv); 66 | PHP_FUNCTION(glGetString); 67 | PHP_FUNCTION(glgetteximage); 68 | PHP_FUNCTION(glgettexlevelparameterfv); 69 | PHP_FUNCTION(glgettexlevelparameteriv); 70 | PHP_FUNCTION(glgettexparameterfv); 71 | PHP_FUNCTION(glgettexparameteriv); 72 | PHP_FUNCTION(glhint); 73 | PHP_FUNCTION(glisenabled); 74 | PHP_FUNCTION(glistexture); 75 | PHP_FUNCTION(gllinewidth); 76 | PHP_FUNCTION(gllogicop); 77 | PHP_FUNCTION(glpixelstoref); 78 | PHP_FUNCTION(glpixelstorei); 79 | PHP_FUNCTION(glpointsize); 80 | PHP_FUNCTION(glpolygonmode); 81 | PHP_FUNCTION(glpolygonoffset); 82 | PHP_FUNCTION(glpolygonstipple); 83 | PHP_FUNCTION(glreadbuffer); 84 | PHP_FUNCTION(glreadpixels); 85 | PHP_FUNCTION(glscissor); 86 | PHP_FUNCTION(glstencilfunc); 87 | PHP_FUNCTION(glstencilmask); 88 | PHP_FUNCTION(glstencilop); 89 | PHP_FUNCTION(glteximage2d); 90 | PHP_FUNCTION(gltexparameterf); 91 | PHP_FUNCTION(gltexparameterfv); 92 | PHP_FUNCTION(gltexparameteri); 93 | PHP_FUNCTION(gltexparameteriv); 94 | PHP_FUNCTION(gltexsubimage1d); 95 | PHP_FUNCTION(gltexsubimage2d); 96 | PHP_FUNCTION(glviewport); 97 | PHP_FUNCTION(glGenVertexArrays); 98 | PHP_FUNCTION(glBindVertexArray); 99 | PHP_FUNCTION(glGenBuffers); 100 | PHP_FUNCTION(glBindBuffer); 101 | PHP_FUNCTION(glbufferdata); 102 | PHP_FUNCTION(glCreateShader); 103 | PHP_FUNCTION(gldeletevertexarrays); 104 | PHP_FUNCTION(gldeletebuffers); 105 | PHP_FUNCTION(gldeleteshader); 106 | PHP_FUNCTION(gldeleteprogram); 107 | PHP_FUNCTION(glshadersource); 108 | PHP_FUNCTION(glcompileshader); 109 | PHP_FUNCTION(glattachshader); 110 | PHP_FUNCTION(glbindfragdatalocation); 111 | PHP_FUNCTION(gllinkprogram); 112 | PHP_FUNCTION(gluseprogram); 113 | PHP_FUNCTION(glcreateprogram); 114 | PHP_FUNCTION(glgetattriblocation); 115 | PHP_FUNCTION(glenablevertexattribarray); 116 | PHP_FUNCTION(gldisablevertexattribarray); 117 | PHP_FUNCTION(glvertexattribpointer); 118 | PHP_FUNCTION(glGetUniformLocation); 119 | PHP_FUNCTION(glActiveTexture); 120 | PHP_FUNCTION(glUniformMatrix4fv); 121 | PHP_FUNCTION(glUniform1i); 122 | PHP_FUNCTION(glUniform3f); 123 | 124 | #endif 125 | -------------------------------------------------------------------------------- /tests/extension-loading.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Extension opengl is loaded. 3 | --DESCRIPTION-- 4 | This test checks if the compiled extension is loaded. 5 | --FILE-- 6 |